题目描述
扫雷游戏你一定玩过吧!现在给你若干个n×m的地雷阵,请你计算出每个矩阵中每个单元格相邻单元格内地雷的个数,每个单元格最多有8个相邻的单元格。 0< n,m< =100
(注意两个矩阵之间应该有一个空行,由于oj的格式化这里不能显示出来)
数据规模和约定
0< n,m< =100
输入
输入包含若干个矩阵,对于每个矩阵,第一行包含两个整数n和m,分别表示这个矩阵的行数和列数。接下来n行每行包含m个字符。安全区域用‘.’表示,有地雷区域用’*‘表示。当n=m=0时输入结束。
输出
对于第i个矩阵,首先在单独的一行里打印序号:“Field #i:”,接下来的n行中,读入的’.'应被该位置周围的地雷数所代替。输出的每两个矩阵必须用一个空行隔开。
样例输入
4 4
*...
....
.*..
....
3 5
**...
.....
.*...
0 0
样例输出
Field #1:
*100
2210
1*10
1110
Field #2:
**100
33200
1*100
此题背景是扫雷,只要按照扫雷的规则来思考本题便易于求解:
构造两个数组,一个用来存放输入的数据,一个用来存放输出数据中的数字。
1.这里看到输出中有“*”字符,可能会想到将输出定义为char类型的数组之后将字符类型的数字转化为int类型。
这样做起来会比较繁杂,其实只需要将数字存入到输出数组的相应位置,当需要输出星号字符时,只需要判断输入数组该位置元素是不是星号即可。
2.整体思路就是循环整个输入数组,当遇到星号时便判断星号的位置,分别判断星号周围8个位置是否需要+1即可。
#include<bits/stdc++.h>
using namespace std;
const int maxn=105;
int main()
{
int n,m;
char MS[maxn][maxn];
int result[maxn][maxn];
int cnt=1;
while(cin>>n>>m&&n!=0&&m!=0)
{
memset(result,0,sizeof(result));
for(int i=0; i<n; i++)
for(int j=0; j<m; j++)
{
cin>>MS[i][j];
if(MS[i][j]=='*')
{
if(i-1>=0)
result[i-1][j]++;
if(i+1<n)
result[i+1][j]++;
if(j-1>=0)
result[i][j-1]++;
if(j+1<m)
result[i][j+1]++;
if(i-1>=0&&j-1>=0)
result[i-1][j-1]++;
if(i-1>=0&&j+1<m)
result[i-1][j+1]++;
if(i+1<n&&j-1>=0)
result[i+1][j-1]++;
if(i+1<n&&j+1<m)
result[i+1][j+1]++;
}
}
cout<<"Field #"<<cnt<<":"<<endl;
cnt++;
for(int i=0; i<n; i++)
{
for(int j=0; j<m; j++)
{
if(MS[i][j]=='*')
cout<<'*';
else
cout<<result[i][j];
}
cout<<endl;
}
cout<<endl;
}
return 0;
}