用旋转原语与行反转原语复合出全部 8 种候选图案,按序号从小到大与目标逐表比较,取第一个匹配的序号。
OJ: roj
题目 ID: 2005
难度:入门
标签:模拟
创建: 2026-10-01 02:26
更新: 2026-10-06 09:21
题目描述
给定两个 src 与 dst,判定 src 经 #1 旋转 90°、#2 旋转 180°、#3 旋转 270°、#4 水平翻转、#5 翻转后再旋转、#6 不变中哪种变成 dst,输出最小序号,无法得到输出 7。
思路
旋转 90°(dst,首个一致的序号即答案,全不匹配输出 7。
参考代码
Python 版:
python
#!/usr/bin/env python3
# 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-10-01 02:26
# update_at: 2026-10-01 02:26
def rotate_cw(g: list[str]) -> list[str]:
"""顺时针旋转 90°:把原图行倒序后按列拼接(新图第 r 行 = 原图第 r 列自下而上)。"""
return [''.join(row) for row in zip(*g[::-1])]
def solve() -> None:
it = iter(sys.stdin.buffer.read().split())
n = int(next(it))
src = [next(it).decode() for _ in range(n)] # 转换前图案
dst = [next(it).decode() for _ in range(n)] # 转换后图案
r90, r180, r270 = rotate_cw(src), rotate_cw(rotate_cw(src)), rotate_cw(rotate_cw(rotate_cw(src)))
mirror = [row[::-1] for row in src] # #4:水平翻转(每行倒序)
m90, m180, m270 = (rotate_cw(mirror), rotate_cw(rotate_cw(mirror)),
rotate_cw(rotate_cw(rotate_cw(mirror)))) # #5 的三种组合
# 按序号从小到大列出全部候选,序号 5 对应三种"翻转后再旋转"
candidates = ((1, r90), (2, r180), (3, r270), (4, mirror),
(5, m90), (5, m180), (5, m270), (6, src))
print(next((no for no, pat in candidates if pat == dst), 7))
if __name__ == "__main__":
import sys
solve()C++ 版(同一算法):
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-10-06 09:17
* update_at: 2026-10-06 09:17
*/
#include <iostream>
using namespace std;
typedef long long ll;
const int MAXN = 15;
char src[MAXN][MAXN];
char dst[MAXN][MAXN];
char tmp[MAXN][MAXN];
char buf[MAXN][MAXN];
int n;
// 将 g 顺时针旋转 90° 存入 res
void rotate_cw(char g[MAXN][MAXN], char res[MAXN][MAXN]) {
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
res[j][n - 1 - i] = g[i][j];
}
// 将 g 水平翻转存入 res
void mirror(char g[MAXN][MAXN], char res[MAXN][MAXN]) {
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
res[i][n - 1 - j] = g[i][j];
}
// 比较两个图案是否完全相同
bool same(char a[MAXN][MAXN], char b[MAXN][MAXN]) {
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() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n;
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
cin >> src[i][j];
for (int i = 0; i < n; i++)
for (int j = 0; j < n; j++)
cin >> dst[i][j];
// 候选图案:#1 旋转90°,#2 旋转180°,#3 旋转270°,#4 水平翻转,
// #5 翻转后再旋转90°/180°/270°,#6 原样
char r90[MAXN][MAXN], r180[MAXN][MAXN], r270[MAXN][MAXN];
char mir[MAXN][MAXN], m90[MAXN][MAXN], m180[MAXN][MAXN], m270[MAXN][MAXN];
rotate_cw(src, r90);
rotate_cw(r90, r180);
rotate_cw(r180, r270);
mirror(src, mir);
rotate_cw(mir, m90);
rotate_cw(m90, m180);
rotate_cw(m180, m270);
if (same(r90, dst)) { cout << 1 << '\n'; return 0; }
if (same(r180, dst)) { cout << 2 << '\n'; return 0; }
if (same(r270, dst)) { cout << 3 << '\n'; return 0; }
if (same(mir, dst)) { cout << 4 << '\n'; return 0; }
if (same(m90, dst)) { cout << 5 << '\n'; return 0; }
if (same(m180, dst)) { cout << 5 << '\n'; return 0; }
if (same(m270, dst)) { cout << 5 << '\n'; return 0; }
if (same(src, dst)) { cout << 6 << '\n'; return 0; }
cout << 7 << '\n';
return 0;
}