题目
题解
实现题。
先说一下题目啥意思,出题人的描述水平有限:
米字型区域输出字母,其他输出点,字母从外层到内层是字典序增大的。
(“沿着西北、正北、东北、正西、正东、西南、正南、东南八个方向……”,听着就离谱)
这种题的本质就是找规律分块输出,控制循环边界。
我们对行列如此编号:
我们分成四个角分别输出,中间的一行ABCBA
单独输出。
四个角是这样划分的:
此情况下当行号和列号相等时输出字母,否则输出点。字母输出也很有规律,第0行输出A,第1行输出B,……,明白了吧。
对于第二列前两行的字母(如下图),我们可以直接根据行号输出,只要在输出完上述的字母和点之后输出一下一个字母即可。
对于右上角的输出:
与左上角的输出唯一的一点不同是当i+j = 1
时输出字母,字母还是根据行号输出。
至此上半部分已经输出完了。
我们单独输出编号为2的这一行
putchar(n - abs(n-i) + 65)
这是我的输出方式,i为列号。(我这里的n是题目要求输入的n-1)
i: 0 1 2 3 4
abs(2-i): 2 1 0 1 2
2-abs(2-i): 0 1 2 1 0
这样就可以根据ASCII码输出字母了。
对于下半部分的输出与上半部分的输出类似,只需要稍微将行遍历的顺序逆序即可。
代码
#include<bits/stdc++.h>
using namespace std;
int n;
int main()
{
cin>>n;
n --; // 单纯为了方便控制下面的编号从0开始遍历
for(int i = 0;i < n;i ++) {
for(int j = 0;j < n;j ++)
if(i == j) putchar(i + 65); // i=j时,输出字母,遍历的这一行+65为ASCII码
else putchar('.');
putchar(i + 65); // 单独输出中心一列的字母
for(int j = 0;j < n;j ++) // 类似于左半部分
if(i+j == n-1) putchar(i + 65); // 输出字母的条件是i+j=n-1
else putchar('.');
puts("");
}
for(int i = 0;i <= 2*n;i ++) putchar(n - abs(n-i) + 65); puts(""); // ABCBA
for(int i = n-1;i >= 0;i --) { // 与上半部分唯一的区别i从n-1开始递减
for(int j = 0;j < n;j ++)
if(i == j) putchar(i + 65);
else putchar('.');
putchar(i + 65);
for(int j = 0;j < n;j ++)
if(i+j == n-1) putchar(i + 65);
else putchar('.');
puts("");
}
return 0;
}