開啟章節選單

10189 Minesweeper

題目連結

題目翻譯

踩地雷遊戲!給你一個 n×m 的地圖,其中 * 代表地雷,. 代表安全格。請把每個安全格換成它周圍 8 個格子中地雷的數量。

輸入

多組測資,每組第一行是 n m,接下來 n 行每行 m 個字元(*.),讀到 0 0 停止。

輸出

每組輸出 Field #x: 後接轉換後的地圖,地圖之間空一行。

解題思路

直接讀入地圖後,對每個格子判斷:

  • 若是 * 就直接輸出 *
  • 若是 . 就用雙層迴圈(p, q 各跑 -1 到 1)掃描周圍 9 格(含自己),統計是 * 的格子數量並輸出

注意邊界條件:i+pj+q 都必須在 [0, n)[0, m) 範圍內才計入。

地圖之間的空行用 (t ? "\n" : "") 處理,第一個地圖前不印空行。

程式碼

//author: Piau
#include <bits/stdc++.h>
using namespace std;

#define pb push_back
#define fi first
#define se second
#define INF LONG_LONG_MAX/1000
#define WA() cin.tie(0)->sync_with_stdio(0)
#define all(x) (x).begin(), (x).end()
#define int long long
#define PII pair<int, int>

signed main() { WA();
    for (int n, m, t = 0; cin >> n >> m, n+m;) {
        cout << (t ? "\n" : "") << "Field #" << ++t << ":\n";
        vector<vector<char>> v(n, vector<char>(m));
        for (auto &i : v) for (auto &j : i) cin >> j;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                if (v[i][j] == '*') cout << '*';
                else {
                    int cnt = 0;
                    for (int p = -1; p <= 1; p++) for (int q = -1; q <= 1; q++) cnt += i+p >= 0 && j+q >= 0 && i+p < n && j+q < m && v[i+p][j+q] == '*';
                    cout << cnt;
                }
            }
            cout << '\n';
        }
    }
}