開啟章節選單
10189 Minesweeper
題目連結
題目敘述
你玩過「踩地雷(Minesweeper)」這款小遊戲嗎?這是一款出現在某個作業系統裡的小遊戲(我們一時想不起來是什麼作業系統)
遊戲的目標是在一個 M × N
的格子地圖中,找出所有地雷的位置。為了幫助你,遊戲會在安全格子中顯示一個數字,表示 這個格子周圍(最多 8 個相鄰格子)有多少顆地雷
舉例
假設你有下面這個 4 × 4
的地圖,其中 *
表示地雷, .
表示安全格子:
*........*......
那麼轉換後的地圖應該是這樣:
*100 2210 1 * 10 1110
如上所示,每個安全格子上的數字,就是它周圍八個格子裡地雷的數量(橫、直、斜都算)
輸入說明
輸入包含多個地圖,每張地圖格式如下:
第一行:
n m
n
是地圖的行數,m
是地圖的列數(保證0 < n, m ≤ 100
)
接下來n
行,每行剛好m
個字元,只會包含:*
表示地雷.
表示安全格子
當讀到n = 0
且m = 0
時,表示輸入結束,這一行不需處理
輸出說明
對每張地圖,輸出格式如下:
Field #x : 地圖結果
其中:
x
是地圖的編號(從 1 開始編號)- 原本是
'.'
的格子,要換成周圍地雷數量(0~8) - 原本是
'*'
的格子維持不變 - 每張地圖輸出後,要空一行,但最後一張輸出後不要再多印空行
解題思路
- 定義方向陣列
- 讀取地圖
- 讀取地圖並先把
.
換成'0'
- 計算每個非地雷格子的周圍地雷數
- 輸出地圖
程式碼
#include <bits/stdc++.h> #define f first #define s second using namespace std; int dir[8][2] = {{1, 0}, {-1, 0}, {0, 1}, {0, -1}, {1, 1}, {1, -1}, {-1, 1}, {-1, -1}}; int main() { int n, m, field = 0; while (cin >> n >> m && n && m) { if (field) cout << endl; vector<string> vc(n); for (int i = 0; i < n; i++) { cin >> vc[i]; for (int j = 0; j < m; j++) { if (vc[i][j] == '.') vc[i][j] = '0'; } } for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { pair<int, int> p = {i, j}; // 現在座標 if (vc[p.f][p.s] == '0') { for (int k = 0; k < 8; k++) { pair<int, int> now = {p.f + dir[k][0], p.s + dir[k][1]}; // 周圍8個座標 /* . . . . x . . . . */ if (0 <= now.f && now.f < n && 0 <= now.s && now.s < m) { // 如果在界內 if (vc[now.f][now.s] == '*') { vc[p.f][p.s] += 1; } } } } } } // 輸出 cout << "Field #" << ++field << ":" << endl; for (int i = 0; i < n; i++) { for (int j = 0; j < m; j++) { cout << vc[i][j]; } cout << endl; } // } return 0; }