原题链接
解题思路
题目说明了从矩阵左上角开始,初始方向为向下。那我们可以想到,顺着向下的方向输出直到不可再向下,然后应该往逆时针方向继续走。
方向改变的顺序是下,右,上,左。
于是我们写出朝这四个方向走一步的增量矩阵。
int direction[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; // 下右上左
实现时:
- 变量d表示方向,0表示下,1表示右,2表示上,3表示左。d的初值为1。
- 变量x, y表示当前输出的数的位置
- 变量times表示已经输出的个数,当输出数times不足n*m时,进入循环。
- 循环中先输出x, y处的数,然后更新x, y。更新时只需要根据当前方向d的增量矩阵更新。(x += direction[d][0], y += direction[d][1])
- 注意要判断d这个方向是否还可以前进,如果不行,逆时针更新d。d = (d+1)%4即可。
源代码
#include<iostream>
using namespace std;
const int maxn = 210;
int num[maxn][maxn];
bool check[maxn][maxn] = {false};
int direction[4][2] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}}; // 下右上左
int main(){
int n, m;
scanf("%d%d",&n, &m);
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
scanf("%d",&num[i][j]);
}
}
int x=0, y=0, times = 0;
// 0, 1, 2, 3分别表示下,右,上,左
int d = 0;
while(times < n*m){
if(!check[x][y]){
printf("%d ", num[x][y]); // 奇了怪了,这怎么会错?
check[x][y] = true;
times++;
}
// 如果朝着d方向走一步不可行,就逆时针改变方向。
if(x+direction[d][0] == n || y+direction[d][1] == m || x+direction[d][0] == -1 || y+direction[d][1] == -1){
d = (d+1)%4;
}
else if(check[x+direction[d][0]][y+direction[d][1]]){
d = (d+1)%4;
}
// 更新位置
x += direction[d][0];
y += direction[d][1];
}
return 0;
}