扫雷游戏地雷数计算

GitHub跳转原题关系图返回列表

对每个非雷格检查八个合法邻居,统计其中星号数量并输出。

OJ: noi_openjudge

题目 ID: ch0108-14

难度:入门

标签:矩阵模拟python

日期: 2026-07-30 23:01

题意

根据雷区中 * 的位置,输出每个非雷格周围八个方向的地雷数。

思路

枚举八个方向,并在访问前判断邻居坐标仍在矩阵内。雷格原样输出,非雷格输出命中 * 的数量。

代码

cpp
#include <cstdio>
#include <cstring>
int n,m;
int fx[8][2] = {
    1,0,
    0,1,
    -1,0,
    0,-1,
    1,1,
    1,-1,
    -1,-1,
    -1,1
};
char str[200][200];

void init(){
    scanf("%d%d",&n,&m);
    int i;
    for (i=1;i<=n;i++){
        scanf("%s",str[i]+1);
    }
}

int calc(int x,int y){
     int i;
     int sum = 0;
     for (i=0;i<8;i++){
         int nx = x + fx[i][0];
         int ny = y + fx[i][1];
         if( str[nx][ny] == '*')
             sum += 1;
     }
     return sum;
}
int main(){
    init();
    int i,j;
    for (i=1;i<=n;i++){
        for (j=1;j<=m;j++){
            if( str[i][j] == '*') continue;
            str[i][j] = calc(i, j) +'0';
        }
    }
    for (i=1;i<=n;i++){
        printf("%s\n",str[i]+1);
    }
    return 0;
}

复杂度

总结

Python代码

python
row_count, column_count = map(int, input().split())
field = [input().strip() for _ in range(row_count)]
directions = ((-1, -1), (-1, 0), (-1, 1), (0, -1), (0, 1), (1, -1), (1, 0), (1, 1))

for row in range(row_count):
    output = []
    for column in range(column_count):
        if field[row][column] == "*":
            output.append("*")
            continue
        mines = sum(0 <= row + dx < row_count and 0 <= column + dy < column_count and field[row + dx][column + dy] == "*" for dx, dy in directions)
        output.append(str(mines))
    print("".join(output))

C++代码

cpp
#include <cstdio>
#include <cstring>
int n,m;
int fx[8][2] = {
    1,0,
    0,1,
    -1,0,
    0,-1,
    1,1,
    1,-1,
    -1,-1,
    -1,1
};
char str[200][200];

void init(){
    scanf("%d%d",&n,&m);
    int i;
    for (i=1;i<=n;i++){
        scanf("%s",str[i]+1);
    }
}

int calc(int x,int y){
     int i;
     int sum = 0;
     for (i=0;i<8;i++){
         int nx = x + fx[i][0];
         int ny = y + fx[i][1];
         if( str[nx][ny] == '*')
             sum += 1;
     }
     return sum;
}
int main(){
    init();
    int i,j;
    for (i=1;i<=n;i++){
        for (j=1;j<=m;j++){
            if( str[i][j] == '*') continue;
            str[i][j] = calc(i, j) +'0';
        }
    }
    for (i=1;i<=n;i++){
        printf("%s\n",str[i]+1);
    }
    return 0;
}

复杂度

每格检查固定八个方向,时间复杂度为 O(nm)O(nm),额外空间为 O(1)O(1)(不含输入)。

总结

八方向网格题可把方向向量固定为一个元组后复用。