题目描述
在一张 n×m 的地图上,有一些地雷,用 1 表示,其余没有地雷的地方用 0 表示;如果某个地雷被引爆了,那么它的波及范围会炸掉 周围八个位置的土地和该地雷所在位置的土地,如果在它的八个位置上也有地雷,那么这些地雷将会连锁反应,继续引爆,爆炸后的土地用 2 表示。请你编写程序,输出引爆某个地雷后地图的模样。
输入
输入共计 n+2行:第一行包含两个整数:n(1≤n≤100),m(1≤m≤100),表示地图的大小为 n×m。
第 2 到 n+1 行,每行包含 m 个字符,表示地图的样貌。
第 n+2 行包含两个整数:x(1≤x≤n),y(1≤y≤m),表示地图上指定开始(引爆)的坐标。如果指定的坐标是土地,也就不需要引爆任何地雷。输出
输出 n 行,每行包含 m 个数,表示爆炸后的地图模样。
样例输入 复制
5 5 10100 01000 00000 00000 00001 1 1
样例输出 复制
22220 22220 22200 00000 00001
代码:
#include <bits/stdc++.h>
using namespace std;
int n,m,x,y;
char sn[1010][1010];
bool vis[1010][1010];
int dx[11]={-1,-1,-1,0,1,1,1,0},dy[11]={1,0,-1,-1,-1,0,1,1};//向八个方向探索
void bfs(){
queue<pair<int,int> > q;
q.push({x,y});//入队
while(q.size()){
pair<int,int> now=q.front();//取队头
int a=now.first,b=now.second;
q.pop();//出队
for(int i = 0;i<=7;i++){
int xx=a+dx[i],yy=b+dy[i];
if(xx>=1&&xx<=n&&yy>=1&&yy<=m){
sn[xx][yy]='2';//地雷的八个方向都被引爆
if(vis[xx][yy]==1){//如果周围八个方向有地雷
vis[xx][yy]=0;//标记这个地雷引爆过了
q.push({xx,yy});//入队
}
}
}
}
}
int main(){
cin >> n >> m;
for(int i = 1;i<=n;i++){
for(int j = 1;j<=m;j++){
cin >> sn[i][j];
if(sn[i][j]=='1') vis[i][j]=1;//如果是地雷标记一下 方便引爆改变数字时不忘记搜索周围的地雷
}
}
cin >> x >> y;
if(sn[x][y]=='1'){//如果开始引爆的点是地雷才进行清除
sn[x][y]='2';
bfs();
}
for(int i = 1;i<=n;i++){//输出引爆后的地图
for(int j = 1;j<=m;j++){
cout << sn[i][j];
}
cout << "\n";
}
return 0;
}