題目: UVa - 10189 - Minesweeper

題目說明

每筆測資開始於兩個數字,表示地雷的地圖大小,隨後是地圖的資訊,算出地圖上的每個點的九宮格內共有幾顆地雷,若該點為地雷則輸出 *,否則輸出該數。

解題思路

定義一個大小為 102 * 102 的陣列 ( 上下左右各預留一行可以省去一些判斷 ),在每筆測資運算開始前,先將陣列清空。讀取測資時,使用 String 一行一行讀取,再使用 find() 找到 * 的位置,並將陣列內對應該點位置的九宮格的數字都 + 1 ,最後再將這個位置設為其他字元 ( 我是設為 . ),避免重複運算。

參考解法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
#include <vector>

using namespace std;

int result[102][102] = {};

void clearResult(int n, int m)
{
for (int i = 0; i < n; ++i)
for (int j = 0; j < m; ++j)
result[i][j] = 0;
}

void addResult(int n, int m)
{
++result[n - 1][m - 1];
++result[n][m - 1];
++result[n + 1][m - 1];

++result[n - 1][m];
++result[n + 1][m];

++result[n - 1][m + 1];
++result[n][m + 1];
++result[n + 1][m + 1];

result[n][m] = -100;
}

void outputResult(int n, int m)
{
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
if (result[i][j] < 0)
cout << "*";
else
cout << result[i][j];
cout << endl << endl;
}
}

int main()
{
int n, m, casenum = 1;
size_t pos;
string map;

while (cin >> n >> m)
{
if (!n && !m)
break;

clearResult(n + 2, m + 2);

for (int i = 0; i < n; ++i)
{
cin >> map;

while ((pos = map.find('*')) != string::npos)
{
map[pos] = '.';
addResult(i + 1, pos + 1);
}
}

cout << "Field #" << casenum << ":" << endl;
outputResult(n, m);
++casenum;
}
}

2021/02/09 Rewrite

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
#include <bits/stdc++.h>

using namespace std;

// reference: https://ppt.cc/f01ivx

static auto __ = []
{
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
return 0;
}();

int n, m;
char field[102][102];

void init()
{
memset(field, '0', sizeof(field));
}

void Fill(int y, int x)
{
for (int i = -1; i <= 1; ++i) for (int j = -1; j <= 1; ++j)
if (field[y + i][x + j] != '*') ++field[y + i][x + j];
}

void solve()
{
char c;
for (int i = 1; i <= n; ++i) for (int j = 1; j <= m; ++j)
{
cin >> c;
if (c == '*') field[i][j] = '*', Fill(i, j);
}
}

void print()
{
static int Case = 0;
if (Case) cout << '\n';
cout << "Field #" << ++Case << ":\n";

for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j) cout << field[i][j];
cout << '\n';
}
}

int main()
{
while (cin >> n >> m && !(!n && !m))
{
init();
solve();
print();
}
}