配对游戏(中二羊)

配对游戏(game.cpp)

题目

【题目描述】

ZEY在玩一个电脑游戏,这个游戏由一个 \(n* m\) 的棋盘和各种图案组成,有些格子中有图案,有些格子是空的。ZEY需要找出相同的图案,然后消除它们,ZEY觉得这个游戏太简单了!
小W同学在-旁观看了整个游戏过程,然后提出新的规则:对于两个相同的图案,从一个图案开始画一条线连接另-个图案,这条线:
(1)只能往上下左右方向走;
(2)只能经过空白的格子;
(3)不能超出棋盘边界;
(4)只能转2次弯。
只有找到连线方法才能消除格子。ZEY顿时觉得智商不够用了,于是ZEY希望能用程序解决这个问题。
现在给出这个 \(n* m\) 的棋盘上的图案,不同的图案用数字 \(1,2,3......\) 来表示,空格子用数字 \(0\) 来表示(保证每个非零整数只出现 \(2\) 次)。ZEY提出了-些坐标对,请你判断,每对坐标上的图案是否能够消除。

【输入说明】

输入文件名为game.in。输入为多行
第一行输入两个整数 \(n\)\(m\)
接下来 \(n\) 行,每行 \(m\) 个整数,示棋盘上每个格子的状态。
接下来一行输入一个整数 \(q\) ,表示ZEY提出的坐标对的数量。
接下来 \(q\) 行,每行输入 \(4\) 个整数,分别是两个格子的坐标 \(x1,y1,x2,y2\)

【输出说明】

输出文件名为game.out
输出 \(q\) 行,分两种情况:如果第 \(i\) 对坐标的格子可以消除,则输出 \(YES\) ;否则输出 \(NO\)

输入样例1:

2 2
1 0
0 1
1
1 1 2 2

输出样例1:

YES

输入样例2:

3 4
1 0 2 3
2 0 0 4
3 4 0 1
2
1 3 2 1
1 1 3 4

输出样例2:

YES
NO

【样例说明】

这里只说明样例2:对于第一个坐标对,从 \((1,3)\) 出发,连线可以连到 \((2,1)\) ,因此输出 \(YES\) ,对于第二个坐标对,从 \((1,1)\) ,连续需要转弯4次才能到达 \((3,4)\) ,因此输出 \(NO\)

【数据范围】

对于 \(60%\) 的数据, \(2\le n,m\le 100\)\(1\le q\le 50\)
对于 \(100%\) 的数据, \(2\le n,m\le 1000\)\(1\le q\le 100\)

题解

一个简单的深搜

代码:

#include<cstdio>
#include<cstring>
int m,n,kkk[1005][1005],x1,y1,x2,y2,hx[]={0,1,-1,0,0},zy[]={0,0,0,1,-1},fx[]={0,1,2,3,4};
bool pd[1005][1005],sb;
void dfs(int x,int y,int from,int fn){
	if(x<0||y<0||x>n||y>m||(kkk[x][y]&&kkk[x][y]!=kkk[x2][y2])||pd[x][y]||sb||fn>2||(fn==2&&x-x2&&y-y2))return;
	if(x==x2&&y==y2&&from){sb=true;return;}
	pd[x][y]=true;	
	for(register int i(1);i<=4;i=-~i){
		if(from!=fx[i]&&from)dfs(x+hx[i],y+zy[i],fx[i],fn+1);
		else dfs(x+hx[i],y+zy[i],fx[i],fn);
	}
	pd[x][y]=false;
}
signed main(){
	int p;
	scanf("%d%d",&n,&m);
	for(register int i(1);i<=n;i=-~i)
		for(register int j(1);j<=m;j=-~j)scanf("%d",&kkk[i][j]);
	scanf("%d",&p);
	while(p--){
		scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
		if(kkk[x1][y1]!=kkk[x2][y2]||!kkk[x1][y1]||!kkk[x2][y2]){
			puts("NO");
			continue;
		}
		sb=false;
		memset(pd,false,sizeof(pd));
		dfs(x1,y1,0,0);
		if(sb)puts("YES");
		else puts("NO");
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值