实现矩阵顺时针旋转和水平反射,按题目编号顺序逐一比较目标图案。
OJ: luogu
题目 ID: P1205
难度:普及-
标签:模拟矩阵字符串python
日期: 2026-07-15 18:58
题意
给出变换前后的 n * n 字符方阵,判断它们属于哪一种变换:旋转 90/180/270 度、水平反射、反射后再旋转、不变,或无效。若多种都满足,输出编号最小的。
思路
把矩阵保存为字符串列表。先写两个函数:
rotate(pattern):顺时针旋转90度;reflect(pattern):水平反射,也就是每一行反转。
然后按题目编号顺序比较:
rotate(before)- 旋转两次
- 旋转三次
reflect(before)- 反射后再旋转一次、两次、三次
- 原图不变
- 以上都不是
因为按编号顺序判断,第一种匹配就是最小编号答案。
这题是矩阵变换模拟,正解已经枚举所有题面情况,不创建 brute.py。
Python 知识
/home/rainboy/mycode/hugo-blog/content/program_language/python/oj_input_output_cheatsheet.md:字符矩阵可直接保存为字符串列表。/home/rainboy/mycode/hugo-blog/content/program_language/python/input_output_and_strings.md:字符串切片row[::-1]可以反转一行。rotate中用列表推导式生成旋转后的每一行。- 字符串列表可以直接用
==判断整个矩阵是否相同。
代码
python
def rotate(pattern):
n = len(pattern)
return ["".join(pattern[n - 1 - row][col] for row in range(n)) for col in range(n)]
def reflect(pattern):
return [row[::-1] for row in pattern]
n = int(input())
before = [input().strip() for _ in range(n)]
after = [input().strip() for _ in range(n)]
rot90 = rotate(before)
rot180 = rotate(rot90)
rot270 = rotate(rot180)
reflected = reflect(before)
if rot90 == after:
print(1)
elif rot180 == after:
print(2)
elif rot270 == after:
print(3)
elif reflected == after:
print(4)
elif rotate(reflected) == after or rotate(rotate(reflected)) == after or rotate(rotate(rotate(reflected))) == after:
print(5)
elif before == after:
print(6)
else:
print(7)cpp
/**
* Author by Rainboy blog: https://rainboylv.com github: https://github.com/rainboylvx
* rbook: -> https://rbook.roj.ac.cn https://rbook2.roj.ac.cn
* rainboy的学习导航网站: https://idx.roj.ac.cn
* create_at: 2026-07-27 00:00
* update_at: 2026-07-27 00:00
*/
#include <bits/stdc++.h>
using namespace std;
int n;
char before[12][12]; // 原始矩阵
char after[12][12]; // 目标矩阵
// 顺时针旋转 90 度
void rotate(char src[12][12], char dst[12][12]) {
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
dst[j][n - 1 - i] = src[i][j];
}
// 水平反射
void reflect(char src[12][12], char dst[12][12]) {
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
dst[i][n - 1 - j] = src[i][j];
}
// 比较两个矩阵是否相等
bool equal(char a[12][12], char b[12][12]) {
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
if (a[i][j] != b[i][j]) return false;
return true;
}
int main() {
cin >> n;
for (int i = 0; i < n; i++) cin >> before[i];
for (int i = 0; i < n; i++) cin >> after[i];
char t1[12][12], t2[12][12], t3[12][12], r[12][12];
rotate(before, t1);
rotate(t1, t2);
rotate(t2, t3);
reflect(before, r);
if (equal(t1, after)) cout << 1;
else if (equal(t2, after)) cout << 2;
else if (equal(t3, after)) cout << 3;
else if (equal(r, after)) cout << 4;
else {
// 反射后再旋转 1~3 次
rotate(r, t1);
rotate(t1, t2);
rotate(t2, t3);
if (equal(t1, after) || equal(t2, after) || equal(t3, after))
cout << 5;
else if (equal(before, after)) cout << 6;
else cout << 7;
}
return 0;
}Pythonic 写法
旋转/翻转函数:
python
def rot(p):
n=len(p)
return [''.join(p[n-1-r][c] for r in range(n)) for c in range(n)]
def ref(p):
return [row[::-1] for row in p]
n=int(input())
b=[input().strip() for _ in range(n)]
a=[input().strip() for _ in range(n)]
r1,r2,r3=rot(b),rot(rot(b)),rot(rot(rot(b)))
rf=ref(b)
if r1==a: print(1)
elif r2==a: print(2)
elif r3==a: print(3)
elif rf==a: print(4)
elif any(x==a for x in (rot(rf),rot(rot(rf)),rot(rot(rot(rf))))): print(5)
elif b==a: print(6)
else: print(7)复杂度
每次矩阵变换需要
总结
矩阵变换题先把基础操作写成函数,再按题目编号顺序组合比较。这样既不漏情况,也能自然满足“输出最小编号”的要求。