top1编程
← 返回题目
题解

扫雷游戏

1 条题解

  • 0
    @ 2026-8-5 0:56:09

    解题思路

    扫雷游戏的规则:一个格子的周围8个格子(上、下、左、右、左上、右上、左下、右下)里有多少颗地雷,就把这个数字填在这个格子上。

    所以我们一个格子一个格子地处理:

    • 如果它是地雷 '',输出时原样输出 '';
    • 如果它不是地雷 '?',就数一数周围 8 个格子里 '*' 的个数,把这个数输出。

    重点:小心越界! 比如左上角的格子没有“上”“左”“左上”的邻居,如果直接去数,数组就访问出界了。所以每数一个邻居前,先检查这个邻居的行、列是否在 1~n、1~m 之内,在界内才算数。

    怎么把 8 个方向写得又短又不漏?用方向数组 dx 和 dy,把 8 个方向(相对原格的偏移)都列出来,用一个循环去枚举就行了。

    输出时注意:格子之间没有空格,每行结束换行。

    参考代码

    // P4454 扫雷游戏:对每个非地雷格数一数周围8个方向上有几颗地雷
    #include <iostream>
    using namespace std;
    
    char a[105][105]; // 雷区地图
    int dx[8] = {-1, -1, -1, 0, 0, 1, 1, 1}; // 周围8个方向的行变化
    int dy[8] = {-1, 0, 1, -1, 1, -1, 0, 1}; // 周围8个方向的列变化
    
    int main() {
        int n, m;
        cin >> n >> m;
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= m; j++)
                cin >> a[i][j]; // 字符之间没有空格,cin逐个读正好
        for (int i = 1; i <= n; i++) {
            for (int j = 1; j <= m; j++) {
                if (a[i][j] == '*') {        // 地雷格原样输出
                    cout << '*';
                    continue;
                }
                int c = 0; // 统计周围地雷数
                for (int k = 0; k < 8; k++) {
                    int ni = i + dx[k], nj = j + dy[k];
                    // 在界内且是地雷就+1
                    if (ni >= 1 && ni <= n && nj >= 1 && nj <= m && a[ni][nj] == '*') c++;
                }
                cout << c;
            }
            cout << endl;
        }
        return 0;
    }
    

    复杂度分析

    • 每个格子都要检查周围 8 个格子,一共有 n×m 个格子,所以时间复杂度是 O(n × m × 8) = O(n × m)。
    • 需要存下整张雷区地图,空间复杂度是 O(n × m)。
    • 1