13.10 螺旋走訪(延伸知識)
從正中央出發、一圈一圈往外繞——這是數字龍捲風(APCS 2017 年 3 月中級)的走法:N \times N 的陣列(N 為奇數),從正中間開始以順時針旋轉的方式走訪每個元素恰好一次,給定起始方向(0 左、1 上、2 右、3 下),依走訪順序輸出所有數字(不空白)。
觀察走法:先走 1 步、轉、走 1 步、轉、走 2 步、轉、走 2 步、轉、走 3 步……步長 1, 1, 2, 2, 3, 3, \dots,每段走完右轉一次,最後一段可能走不滿就結束。題目的方向編號 0 左、1 上、2 右、3 下本身就是順時針,所以右轉還是 (dir + 1) % 4:
#include <bits/stdc++.h>
using namespace std;
// 題目的方向編號:0 左、1 上、2 右、3 下——本身就是順時針,右轉=編號 +1
const int dr[4] = {0, -1, 0, 1};
const int dc[4] = {-1, 0, 1, 0};
int main() {
int n, dir;
cin >> n >> dir;
vector<vector<int>> a(n, vector<int>(n));
for (int r = 0; r < n; r++)
for (int c = 0; c < n; c++)
cin >> a[r][c];
int r = n / 2, c = n / 2; // 從正中央出發
int printed = 1;
cout << a[r][c];
for (int len = 1; printed < n * n; len++) { // 步長 1,1,2,2,3,3,…
for (int twice = 0; twice < 2 && printed < n * n; twice++) {
for (int step = 0; step < len && printed < n * n; step++) {
r += dr[dir]; c += dc[dir];
cout << a[r][c];
printed++;
}
dir = (dir + 1) % 4; // 每段走完右轉
}
}
cout << '\n';
return 0;
}
因為是從中心往外繞,在走滿 N^2 格之前永遠不會出界,所以這一題連 inside 都不需要——printed < n * n 那三個條件就是唯一的煞車。從左上角往內繞的螺旋則相反,每一步都要判邊界或用標記表擋住走過的格子。