根据y总的讲解,写的题解,可以参考一下: https://mp.weixin.qq.com/s/9J_Xx6Pm0eT3nAh7ZzYxgg
#include<iostream>
using namespace std;
const int N = 1010;
int q[N][N];
int n, m;
int main() {
cin >> n >> m;
int dx[ ] = {-1, 0, 1, 0}, dy[ ] = {0, 1, 0, -1};
// 以(x,y)为中心,按顺时针顺序,向上、右、下、左四个方向移动。
// dx[ ]和dy[ ]中记录的是偏移量,也就是往各个方向移动所需的偏移量
// 下标索引表示各自方向的编号,一开始是向右移动的,所以是dx[1],dy[1],d = 1表示向右偏移
int x = 0, y = 0, d = 1; // 初始坐标是(0,0)
for(int i = 1; i <= n*m; ++i) { // 遍历n*m次
q[x][y] = i; // 将这个坐标题目所要求的值,这样也能表明其被走过
int a = x + dx[d], b = y + dy[d];
// a,b是候选新下标,它们经过判断后,如果合法,则分别赋值给x、y,成为新下标(这个新下标是指下一步要走到的位置)
// 如果不合法,则会通过一些系列操作,让a、b合法化(其实也就是更新方向,让x和y分别加上更新方向后的dx[ ]和dy[ ],得到一个新的a、b)
// 判断a和b是否合法(也就是判断是否越界、是否重复访问同一位置)
if(a < 0 || a >= n || b < 0 || b >= m || q[a][b]) {
d = (d + 1) % 4; // 更新方向
a = x + dx[d], b = y + dy[d]; // 重新以x、y为中心,向新的方向走一步,这样a、b就合法化了
}
x = a, y = b; // 确认a、b一定合法后,再进行赋值,此时的(x,y)就是下一个将要走到的位置的坐标
}
for(int i = 0; i < n; ++i) {
for(int j = 0; j < m; ++j) {
cout << q[i][j] << " ";
}
cout << endl;
}
}
易错一:在判断的时候,记得加上q[a][b]判断,判断这个坐标是不是走过