P2670 [NOIP2015 普及组] 扫雷游戏

题目背景

NOIP2015 普及组 T2

题目描述

扫雷游戏是一款十分经典的单机小游戏。在 nn 行 mm 列的雷区中有一些格子含有地雷(称之为地雷格),其他格子不含地雷(称之为非地雷格)。玩家翻开一个非地雷格时,该格将会出现一个数字——提示周围格子中有多少个是地雷格。游戏的目标是在不翻出任何地雷格的条件下,找出所有的非地雷格。

现在给出 nn 行 mm 列的雷区中的地雷分布,要求计算出每个非地雷格周围的地雷格数。

注:一个格子的周围格子包括其上、下、左、右、左上、右上、左下、右下八个方向上与之直接相邻的格子。

输入格式

第一行是用一个空格隔开的两个整数 nn 和 mm,分别表示雷区的行数和列数。

接下来 nn 行,每行 mm 个字符,描述了雷区中的地雷分布情况。字符 \texttt{*}* 表示相应格子是地雷格,字符 \texttt{?}? 表示相应格子是非地雷格。相邻字符之间无分隔符。

输出格式

输出文件包含 nn 行,每行 mm 个字符,描述整个雷区。用 \texttt{*}* 表示地雷格,用周围的地雷个数表示非地雷格。相邻字符之间无分隔符。

输入输出样例

输入 #1
3 3
*??
???
?*?
输出 #1
*10
221
1*1
输入 #2
2 3
?*?
*??
输出 #2
2*1
*21

说明/提示

对于 100\%100%的数据,1≤n≤100, 1≤m≤100,1n100,1m100。

这个题因为矩阵最大就是100*100,所以说直接全部遍历一次也不会超时,比较省事

思路:
先输入这个矩阵,如果输入了 “ * ” 那么在B数组把这个位置标记为-1,随后把这个数组的每一个不是雷的位置遍历,把他边上的雷全部加起来,直接输出这个点就可以了

代码:

#include<iostream>
using namespace std;
char a;
int b[101][101];
int main(){
int n,m;

//输入这个矩阵的宽高
cin>>n>>m;

//因为我们只需要判断输入的是不是*号,所以不需要储存输入的矩阵,用一个char变量就可以了
for(int i=1;i<=n;i++){
  for(int j=1;j<=m;j++){
    cin>>a;

    //判断是不是*号,如果是就在b数组标记为-1
    if(a=='*'){
      b[i][j]=-1;
    }
  }
}

//遍历b数组
for(int i=1;i<=n;i++){
  for(int j=1;j<=m;j++){

    //cnt数组是计算雷的数量的
    int cnt=0;

    //如果当前点是-1,也就是雷,那就直接输出一个*号就行了
    if(b[i][j]==-1){
      cout<<"*";
    }

    //如果当前点不是雷,扫一遍他边上的格子,有雷则cnt自增,把cnt的值直接输出,反正也不会再用到这一格了
    if(b[i][j]!=-1){
      for(int x=-1;x<=1;x++){
        for(int y=-1;y<=1;y++){
          if(b[i+x][j+y]==-1)
             cnt++;
        }
      }
    cout<<cnt;
    }
  }

  //输出换行
  cout<<endl;
}
return 0;
}

//顺带一提我也是新手,交流一下思路,可能代码写的不好

posted @ 2022-08-23 15:19  丷Ghost丷  阅读(53)  评论(0)    收藏  举报