#include<bits/stdc++.h> using namespace std; const int MAXN=510; char ma[MAXN][MAXN],ans[MAXN][MAXN],book[MAXN][MAXN]; int qqq[MAXN][3]; int n,m,a,b; struct f { int x; int y; }; queue<f>q; void bfs(int xx,int yy) { int Next[8][2]={{1,0},{-1,0},{0,1},{0,-1},{1,1},{-1,-1},{1,-1},{-1,1}}; ma[xx][yy]='@'; f t;t.x=xx;t.y=yy; q.push(t); while(!q.empty()) //八连通的联通块 { t=q.front();q.pop(); for(int i=0;i<8;i++) { int tx=t.x+Next[i][0]; int ty=t.y+Next[i][1]; if(tx<1||ty<1||tx>n||ty>m||book[tx][ty]) continue; if(ma[tx][ty]>='0'&&ma[tx][ty]<='9') ans[tx][ty]=ma[tx][ty]; else if(ma[tx][ty]=='.') { f tt; tt.x=tx;tt.y=ty;ans[tx][ty]='0'; book[tx][ty]=1; q.push(tt); } } } } int main() { int T; int i,j,k; char q; cin>>T; while(T--) { cin>>n>>m>>k; memset(book,0,sizeof(book)); for(i=1;i<=n;i++) for(j=1;j<=m;j++) { cin>>ma[i][j]; ans[i][j]='.'; //读入数据,初始化ans数组 } int flag=0; //flag为1说明点雷了 for(int i=1;i<=k;i++) cin>>qqq[i][1]>>qqq[i][2]; //读入查询 for(int i=1;i<=k;i++) { //点雷情况 a=qqq[i][1];b=qqq[i][2]; if(ma[a][b]=='*') { flag=1; cout<<"Game over in step "<<i<<endl; break; } else if(ma[a][b]=='.') //点空白情况 { book[a][b]=1; ans[a][b]='0'; //进入bfs函数 bfs(a,b); } else if(ma[a][b]>='0'&&ma[a][b]<='9') //点数字情况 ans[a][b]=ma[a][b]; } if(!flag) //输出 { for(int i=1;i<=n;i++) { for(int j=1;j<=n;j++) cout<<ans[i][j]; cout<<endl; } } } return 0; }
链接: https://www.nowcoder.com/acm/contest/118/F
来源:牛客网
题目描述
《扫雷》是一款大众类的益智小游戏,于1992年发行。游戏目标是在最短的时间内根据点击格子出现的数字找出所有非雷格子,同时避免踩雷,踩到一个雷即全盘皆输。当某个位置为数字的时,代表它周围的八连通区域中有对应数量的雷。
kirai获取了简化版扫雷(没有标记雷的小旗)的后台数据(后台数据包括所有数字和雷的位置),转换为一个n*m(1≤n, m≤500)的矩阵并对格子类型做了如下标记:
雷被标记为'*';
点开的空白区域标记为'0';
未点开的空白区域标记为'.';
数字1~8代表周围有多少雷;
kirai非常笨,他希望你帮他完成这样的任务:
给定k(1≤k≤min(可扫位置数, 10))个位置坐标和扫雷游戏的后台数据,输出点开指定位置序列后游戏的结果,初始时游戏中没有点开任何位置。
注:数据保证扫雷过程中不会重复点击已扫位置。
输入描述:
输入样例有多组,全部是正整数。首先输入样例组数T(T≤10)。 接下来输入T组数,每组数据第一行包括四个正整数n,m,k(1≤n, m≤500, 1≤k≤min(可扫位置数, 10))分别表示地图的行、列数和即将点开的位置数。紧接着是一个n*m的矩阵,代表扫雷的后台数据,。 矩阵后是k个整数对xi, yi(1≤i≤k, 1≤xi≤n, 1≤yi≤m),表示依次点开的位置。
输出描述:
如果某一步踩到雷,输出"Game over in step x"(不包括引号",表示第x步踩中雷);未踩到雷则根据扫雷的游戏规则更新,并输出最后一步结束后显示给kirai的矩阵。