输入
n
n
n,输出
n
n
n行
n
n
n列的由+
和.
组成的正方形,其中最外面一圈全是+
,第二圈全是.
,…,对于第
i
i
i圈,如果
i
i
i是奇数,那么全是+
,否则全是.
。
输入格式
一行,一个整数 n n n。
输出格式
n n n行,为满足题目要求的正方形。注意不要有行末空格。
样例输入
10
样例输出
++++++++++
+........+
+.++++++.+
+.+....+.+
+.+.++.+.+
+.+.++.+.+
+.+....+.+
+.++++++.+
+........+
++++++++++
数据范围
对于 100 100 100%的数据,保证 2 ≤ n ≤ 100 2≤n≤100 2≤n≤100
解题思路:
虽然本题数据范围不大,可以直接实现数组存储,然后输出
但这里仍然采用无存储的方式实现
二维图形输出,自然采用二重循环实现
关键在于如何调整输出.
还是+
这里通过两条对角线来实现调整
每次输出前反转两条对角线之间要输出的符号,我们具体模拟一下来说明
初始化输出模式..........
然后我们来到第一行,反转之后的输出模式++++++++++
然后我们来到第二行,反转之后的输出模式+........+
然后我们来到第三行,反转之后的输出模式+.++++++.+
…
是不是很好理解?但是没有结束,我们需要特殊处理
因为当前每一次循环执行的动作是简单的:反转,然后输出
但是如果这样的话,前半段输出是对的,后半段就会出现错误,如下
++++++++++
+........+
+.++++++.+
+.+....+.+
+.+.++.+.+
+.+....+.+
+.++++++.+
+........+
++++++++++
..........
所以我们稍微调整一下:
(1)前半段:反转,然后输出
(2)后半段:输出,然后反转
最后,AC代码如下
#include <iostream>
using namespace std;
const int max_n = 100;
char pattern[max_n]; //每行的输出模式
bool save[max_n]; //处理模式的调整
//反转
inline void reverse(char& c) {
if (c == '.') c = '+';
else c = '.';
}
int main() {
int n;
bool change = false;
cin >> n;
for (int i = 0; i < n; i++) pattern[i] = '.';//初始化
for (int i = 0; i < n; i++) {
if (save[i]) {//后半段:先输出,后反转
cout << pattern << endl;
for (int j = 0; j < n; j++) {
if (i == j || i + j == n - 1) {//判断对角线
save[i] = save[n - i] = true;
change = !change;
reverse(pattern[j]);
j++;
while (change) {
reverse(pattern[j]);
if (i == j || i + j == n - 1) {//判断对角线
change = !change;
}
else {
j++;
}
}
}
}
}
else {//前半段:先反转,后输出
int j;
for (j = 0; j < n; j++) {
//特殊判定:如果对角线交于一点
if (i == j && i + j == n - 1) {
reverse(pattern[i]);
}
else {//常规
if (i == j || i + j == n - 1) {//判断对角线
save[i] = save[n - 1 - i] = true;
change = !change;
reverse(pattern[j]);
j++;
while (change) {
reverse(pattern[j]);
if (i == j || i + j == n - 1) {//判断对角线
change = !change;
}
else {
j++;
}
}
}
}
}
cout << pattern << endl;
if (i == n / 2) {//特殊判定:如果对角线交于一点
reverse(pattern[i]);
}
}
}
return 0;
}