1 条题解

  • 0
    @ 2025-6-5 12:59:32

    题解

    题意分析

    题目要求实现扫雷游戏的部分状态显示功能:

    • 游戏在n×nn \times n的网格上进行,包含mm个地雷
    • 输入包含两部分:
      • 地雷分布图(*表示地雷,..表示安全)
      • 玩家点击状态(xx表示已点击,..表示未点击)
    • 需要输出完整游戏板:
      • 已点击的安全位置显示周围地雷数(080-8
      • 若点击到地雷,则显示所有地雷位置
      • 未点击位置显示.

    解题思路

    1. 输入处理:读取网格大小nn,地雷分布和点击状态
    2. 地雷检测:检查是否点击到地雷
    3. 游戏板生成
      • 若点击到地雷,显示所有地雷位置
      • 否则计算每个已点击位置周围的地雷数
    4. 输出结果:按规则输出完整游戏板

    实现步骤

    1. 读取输入:存储地雷分布和点击状态到二维数组
    2. 地雷检查:遍历点击状态,检查是否有点击到地雷
    3. 游戏板计算
      • 对于每个已点击位置,计算88个相邻位置的地雷数
      • 根据是否点击到地雷决定显示方式
    4. 结果输出:逐行打印处理后的游戏板

    代码注释

    #include <iostream>
    #include <vector>
    using namespace std;
    
    int main() {
        int n;
        cin >> n; // 读取网格大小n
        
        // 读取地雷分布图
        vector<vector<char>> mines(n, vector<char>(n));
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                cin >> mines[i][j]; // 存储每个位置是否有雷
            }
        }
        
        // 读取点击状态图
        vector<vector<char>> touched(n, vector<char>(n));
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                cin >> touched[i][j]; // 存储每个位置是否被点击
            }
        }
        
        // 检查是否点击到地雷
        bool mine_touched = false;
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                if (touched[i][j] == 'x' && mines[i][j] == '*') {
                    mine_touched = true; // 标记点击到地雷
                    break;
                }
            }
            if (mine_touched) break;
        }
        
        // 生成并输出游戏板
        for (int i = 0; i < n; ++i) {
            for (int j = 0; j < n; ++j) {
                if (mine_touched) { // 如果点击到地雷
                    if (mines[i][j] == '*') {
                        cout << '*'; // 显示所有地雷
                    } else if (touched[i][j] == 'x') {
                        // 计算已点击位置周围地雷数
                        int count = 0;
                        for (int di = -1; di <= 1; ++di) {
                            for (int dj = -1; dj <= 1; ++dj) {
                                if (di == 0 && dj == 0) continue; // 跳过自身
                                int ni = i + di, nj = j + dj;
                                // 检查相邻位置是否在地雷
                                if (ni >= 0 && ni < n && nj >= 0 && nj < n && mines[ni][nj] == '*') {
                                    ++count;
                                }
                            }
                        }
                        cout << count; // 显示地雷数
                    } else {
                        cout << '.'; // 未点击位置
                    }
                } else { // 没有点击到地雷
                    if (touched[i][j] == 'x') {
                        // 计算已点击位置周围地雷数
                        int count = 0;
                        for (int di = -1; di <= 1; ++di) {
                            for (int dj = -1; dj <= 1; ++dj) {
                                if (di == 0 && dj == 0) continue;
                                int ni = i + di, nj = j + dj;
                                if (ni >= 0 && ni < n && nj >= 0 && nj < n && mines[ni][nj] == '*') {
                                    ++count;
                                }
                            }
                        }
                        cout << count; // 显示地雷数
                    } else {
                        cout << '.'; // 未点击位置
                    }
                }
            }
            cout << endl; // 换行
        }
        
        return 0;
    }
    

    复杂度分析

    • 时间复杂度O(n2)O(n^2),需要遍历n×nn \times n网格两次(输入读取)和一次(结果计算)
    • 空间复杂度O(n2)O(n^2),需要存储地雷分布和点击状态两个n×nn \times n矩阵
    • 1

    信息

    ID
    1613
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    16
    已通过
    1
    上传者