题目
翻译
主要思路
观察本题可知,从最后一列开始顺时针填充
在一轮填充(逆时针绕一圈,比如样例里面从1到12)中,有两个关键点
1 填充步幅:
一行或者一列的填充步幅stride最初是n - 1,然后每轮递减2,当填充步幅是0时,说明只用填充1个空格
2 填充起点:
第一轮填充起点是最后一列第一行,然后一次行 + 1,列 - 1
第一次写错误
- 一开始居然没想到先存在二维数组里再正常打印二维数组就行了
- 太坑了,题目说一次会有多次输入,以为就1个输入
总结
这类题就是找规律
首先找到初始状态(比如第一轮填充步幅是多少),然后研究从一个状态到下一个状态的变化(从第一轮到第二轮填充步幅怎么变化),最后考虑特殊情况(当填充步幅是0该怎么办)
代码
#include <bits/stdc++.h>
using namespace std;
#define MAX_NUM 20
int Data[MAX_NUM][MAX_NUM];
int main() {
int n;
while(scanf("%d", &n) == 1) {
int stride = n - 1;
int count = 1;
int startCol = n - 1;
int startRow = 0;
while(stride >= 0) {
int row = startRow;
int col = startCol;
if(stride == 0) {
Data[row][col] = count;
}
for(int i = 0; i < stride; i++) Data[row++][col] = count++;
for(int i = 0; i < stride; i++) Data[row][col--] = count++;
for(int i = 0; i < stride; i++) Data[row--][col] = count++;
for(int i = 0; i < stride; i++) Data[row][col++] = count++;
startRow++;
startCol--;
stride -= 2;
}
for(int i = 0; i < n; i++) {
for(int j = 0; j < n; j++) {
printf("%d", Data[i][j]);
if(j != n - 1) {
printf(" ");
}
}
printf("\n");
}
}
return 0;
}