F 扫雷

链接: 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的矩阵。

示例1

输入

1
5 5 3
2*11*
*2111
22...
*1...
11...
1 1
3 3
1 2

输出

Game over in step 3

说明

2....
.....
.....
.....
.....
2....
.2111
.2000
.1000
.1000
Game over in step 3

#include <iostream>
#include <cstring>
#include <cctype>
using namespace std;
const int maxn=500+10;
char w[maxn][maxn];
char temp[maxn][maxn];
char vis[maxn][maxn];
int T,m,n,k;

int first=0;
void dfs(int x,int y){
		if(w[x][y]=='.')temp[x][y]='0';
		for(int g=-1;g<=1;g++){
			for(int h=-1;h<=1;h++){
				int newx=x+g;
				int newy=y+h;
				if(newx>=1&&newx<=m&&newy>=1&&newy<=n){
					if(isdigit(w[newx][newy]))
						temp[newx][newy]=w[newx][newy];
					else if(!vis[newx][newy]&&w[newx][newy]=='.'){
						vis[newx][newy]=true;
						dfs(newx,newy);							
					}
						
				}	
			}		
		}		
}	
int main(){
	cin>>T;
	while(T--){
		memset(w,'.',sizeof(w));
		memset(temp,'.',sizeof(temp));
		memset(vis,false,sizeof(vis));
		cin>>m>>n>>k;
		for(int i=1;i<=m;i++)
			for(int j=1;j<=n;j++){
				cin>>w[i][j];
				temp[i][j]='.';
			}
		bool abu=true;
		for(int i=0;i<k;i++){
			int x,y;
			cin>>x>>y;
			if(isdigit(w[x][y]))
				temp[x][y]=w[x][y];
			else if(w[x][y]=='*'){
				if(abu==true){
					first=i+1;
					abu=false;
				}
			}
			else
				dfs(x,y);
		}
		if(abu==true){
			for(int i=1;i<=m;i++){
				for(int j=1;j<=n;j++)
					if(j==1)
						cout<<temp[i][j];
					else
						cout<<" "<<temp[i][j];
				cout<<endl;
			}
		}
		else
			cout<<"Game over in step "<<first<<endl;
	}
	return 0;
} 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值