题目描述
"福"字倒着贴,寓意"福到"。不论到底算不算民俗,本题请你编写程序,把各种汉字倒过来输出。这里要处理的每个汉字是由一个 N × N 的网格组成的,网格中的元素或者为字符 @ 或者为空格。而倒过来的汉字所用的字符由裁判指定。
输入输出格式
| 项目 | 说明 |
|---|---|
| 输入格式 | 第一行:指定字符 + 空格 + N(≤100 的正整数);随后 N 行,每行 N 个字符(@ 或空格) |
| 输出格式 | 倒置的网格;若字正过来倒过去相同,先输出 bu yong dao le 再输出网格 |
样例
输入样例 1:
$ 9
@ @@@@@
@@@ @@@
@ @ @
@@@ @@@
@@@ @@@@@
@@@ @ @ @
@@@ @@@@@
@ @ @ @
@ @@@@@
输出样例 1:
$$$$$ $
$ $ $ $
$$$$$ $$$
$ $ $ $$$
$$$$$ $$$
$$$ $$$
$ $ $
$$$ $$$
$$$$$ $
输入样例 2:
& 3
@@@
@ @
@@@
输出样例 2:
bu yong dao le
&&&
& &
&&&
解题思路
核心操作:网格倒置(旋转 180°)
倒置即坐标变换:(i, j) → (n-1-i, n-1-j)
算法步骤:
- 读取输入 :读取指定字符
c和网格大小n,再读取 n 行字符串 - 判断对称 :遍历网格,检查每个位置
a[i][j]与a[n-1-i][n-1-j]是否相同。如果全部相同,说明字倒过来和原来一样 - 输出结果 :
- 如果对称:先输出
bu yong dao le - 无论如何都输出倒置后的网格(将
@替换为指定字符,空格保持不变)
- 如果对称:先输出
关键点:
- 读取网格时每行末尾的空格需要保留,可以用
list(line).append(' ')补齐到 n 个 - 对称判断:只需遍历左上三角即可(因为
(i,j)和(n-1-i,n-1-j)配对) - 字符替换:倒置网格中
a[n-1-i][n-1-j]为@时输出指定字符
代码实现
Java 代码
java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
String repStr = scanner.next();
char replaceChar = repStr.charAt(0);
int n = scanner.nextInt();
scanner.nextLine();
char[][] a = new char[n][n];
for (int i = 0; i < n; i++) {
String line = scanner.nextLine();
// 补齐空格使每行达到 n 个字符
while (line.length() < n) {
line += " ";
}
for (int j = 0; j < n; j++) {
a[i][j] = line.charAt(j);
}
}
// 判断是否对称(倒过来和原来相同)
boolean symmetric = true;
for (int i = 0; i < n && symmetric; i++) {
for (int j = 0; j < n; j++) {
if (a[i][j] != a[n - 1 - i][n - 1 - j]) {
symmetric = false;
break;
}
}
}
if (symmetric) {
System.out.println("bu yong dao le");
}
// 输出倒置后的网格
for (int i = 0; i < n; i++) {
StringBuilder sb = new StringBuilder();
for (int j = 0; j < n; j++) {
char ch = a[n - 1 - i][n - 1 - j];
sb.append(ch == '@' ? replaceChar : ' ');
}
System.out.println(sb.toString());
}
scanner.close();
}
}
Python 代码
python
def main():
rep, n = input().split()
n = int(n)
a = []
for _ in range(n):
line = input()
# 补齐空格到 n 个字符
line = list(line.ljust(n))
a.append(line)
# 判断是否对称
symmetric = all(a[i][j] == a[n - 1 - i][n - 1 - j] for i in range(n) for j in range(n))
if symmetric:
print("bu yong dao le")
# 输出倒置网格
for i in range(n):
row = ""
for j in range(n):
ch = a[n - 1 - i][n - 1 - j]
row += rep if ch == '@' else ' '
print(row)
if __name__ == "__main__":
main()
运行验证
样例 1 验证
输入:
$ 9
@ @@@@@
@@@ @@@
@ @ @
@@@ @@@
@@@ @@@@@
@@@ @ @ @
@@@ @@@@@
@ @ @ @
@ @@@@@
Python 输出:
$$$$$ $
$ $ $ $
$$$$$ $$$
$ $ $ $$$
$$$$$ $$$
$$$ $$$
$ $ $
$$$ $$$
$$$$$ $
样例 2 验证
输入:
& 3
@@@
@ @
@@@
Python 输出:
bu yong dao le
&&&
& &
&&&
复杂度分析
- 时间复杂度:O(N²),遍历两次 N×N 网格(对称判断 + 输出)
- 空间复杂度:O(N²),存储整个网格
总结
本题考察二维数组的读取、坐标变换和字符串处理。核心在于:
- 倒置坐标映射 :
(i, j) → (n-1-i, n-1-j),即中心对称翻转 - 对称判断 :只需检查
a[i][j] == a[n-1-i][n-1-j],利用配对关系减少比较次数 - 空格处理:读取时需要补齐空格到 n 个字符,否则网格会错位