题解
有一点蛇形矩阵的感觉,依次有四种方向【向右/向左下/向下/向右上】,其中向右和向下每次走一步就要转变方向,而向左下和向右上都是走到越界才转向。直到走完 $n×n$ 个数停止。注意走过的位置不能再走,由于矩阵元素都是正数,所以可以在走完每一步后将对应的元素置0用于标记已经走过。
代码
#include <iostream>
using namespace std;
const int N = 510;
int a[N][N], n;
int dx[4] = {0, 1, 1, -1}, dy[4] = {1, -1, 0, 1};
int main()
{
cin >> n;
for (int i = 0; i < n; i ++ )
for (int j = 0; j < n; j ++ )
cin >> a[i][j];
int i = 0, j = 0, cnt = 0 , t = 0;
cout << a[i][j] << ' ';
cnt ++ ;
while (cnt < n * n)
{
int x = i + dx[t], y = j + dy[t];
// 未遍历过/未越界
if (a[x][y] && x >= 0 && x < n && y >= 0 && y < n)
{
i = x, j = y;
cout << a[i][j] << ' ';
a[i][j] = 0;
cnt ++ ;
if (t == 0 || t == 2) t ++ ; // 向右和向下走一步就要变向
}
else t = (t + 1) % 4; // 遍历过或者越界需要转向
}
cout << endl;
return 0;
}
太绝了!这个思路
秒啊
赞
我有一个地方不理解,就是那个t的取值,每一次的变化是怎么确定的啊,这个不好确定啊!
t = 0 -> 向右走 // t = 1 -> 向左下走 // t = 2 -> 向下走 // t = 3 -> 向右上走
根据z字形扫描的规律可以发现,扫描的方向在这四种状态循环切换,但是需要注意的是向右走/向下走,走一步就要切换到下一种方向,而向左下走和向右上走都是走到越界才切换方向。因此在循环体中,如果判断当前是向右走【
t == 0
】或向下走【t == 2
】则即刻切换方向t ++
,若不是则正常走。当出现越界情况的时候,就需要切换方向了t = (t + 1) % 4
,求模是为了保证在0~3
这四种方向中来回循环。不知道这样解释是否能解决你的疑惑 O(∩_∩)O
哦,这个t取值的顺序是根据在题目中走的顺序依次设定的吗
对的,你需要先观察一下这个z字型扫描的规律。
orz
赞