數字龍捲風

題目說明

這個題目是一個二維陣列路徑問題。題目給定一個二維陣列,求一個由中心開始順時針向外旋轉的路徑,最後將整個路徑上經過的數字輸出出來。這題基本上是一個非常基礎的二維陣列操作,不需要複雜的演算法,只需要根據題目敘述來執行即可。

解題過程

首先我們觀察這個數字龍捲風的移動模式,嘗試尋找它的規律出來。根據測資一我們會發現移動情況如下:

左1、上 1、右 2、下 2、左 3、上 3 ... 左4

你發現規律了嗎?除了他的移動方向是順時鐘外,移動距離每兩次會增加一單位,直到最後一次才出現例外。既然找到規則了,我們就只需要按照這個邏輯實際轉成程式碼即可。

首先第一步一定就是依照題目讀入測資。

cin >> n >> a;
for (int i = 0; i < n; i++) {
    for (int j = 0; j < n; j++) {
        cin >> v[i][j];
    }
}

接下來宣告兩個變數x y,用來記錄當前指向的位置。

int x = n / 2;
int y = n / 2;

接下來寫三層迴圈。第一層 i 迴圈主要用來執行移動距離計次,第二層 j 迴圈很單純只是做兩次,用來處理轉向兩次才會增加移動距離的狀況,第三層的 k 迴圈用來實際執行每次需要移動的距離。

for (int i = 1; i <= n; i++) {
    for (int j = 0; j < 2; j++) {
        for (int k = 1; k <= i; k++) {
            s += to_string(v[x][y]);
            y += r[a][0];
            x += r[a][1];
        }
        a = (a + 1) % 4;
    }
}

現在程式已經會順利紀錄完整個路徑了,但由於最後一次執行其實不需要真的走 n 次,所以我們需要再超出陣列存取範圍時就先將程式終止。只需簡單在每次移動時檢測是否達到結束條件即可。

if (i==n && k==n) {
    cout << s;
    return 0;
}

解題成果

#include <iostream>
#include <string>
using namespace std;

int n, a;
int v[50][50] = {0};
int r[4][2] = {{-1, 0}, {0, -1}, {1, 0}, {0, 1}};
string s = "";

int main() {
    cin >> n >> a;
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            cin >> v[i][j];
        }
    }

    int x = n / 2;
    int y = n / 2;
    for (int i = 1; i <= n; i++) {
        for (int j = 0; j < 2; j++) {
            for (int k = 1; k <= i; k++) {
                s += to_string(v[x][y]);
                y += r[a][0];
                x += r[a][1];

                if (i==n && k==n) {
                    cout << s;
                    return 0;
                }
            }
            a = (a + 1) % 4;
        }
    }
}