连连看
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Submission(s): 34702 Accepted Submission(s): 8625
Problem Description
“连连看”相信很多人都玩过。没玩过也没关系,下面我给大家介绍一下游戏规则:在一个棋盘中,放了很多的棋子。如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子),而且线的转折次数不超过两次,那么这两个棋子就可以在棋盘上消去。不好意思,由于我以前没有玩过连连看,咨询了同学的意见,连线不能从外面绕过去的,但事实上这是错的。现在已经酿成大祸,就只能将错就错了,连线不能从外围绕过。
玩家鼠标先后点击两块棋子,试图将他们消去,然后游戏的后台判断这两个方格能不能消去。现在你的任务就是写这个后台程序。
玩家鼠标先后点击两块棋子,试图将他们消去,然后游戏的后台判断这两个方格能不能消去。现在你的任务就是写这个后台程序。
Input
输入数据有多组。每组数据的第一行有两个正整数n,m(0<n<=1000,0<m<1000),分别表示棋盘的行数与列数。在接下来的n行中,每行有m个非负整数描述棋盘的方格分布。0表示这个位置没有棋子,正整数表示棋子的类型。接下来的一行是一个正整数q(0<q<50),表示下面有q次询问。在接下来的q行里,每行有四个正整数x1,y1,x2,y2,表示询问第x1行y1列的棋子与第x2行y2列的棋子能不能消去。n=0,m=0时,输入结束。
注意:询问之间无先后关系,都是针对当前状态的!
注意:询问之间无先后关系,都是针对当前状态的!
Output
每一组输入数据对应一行输出。如果能消去则输出"YES",不能则输出"NO"。
Sample Input
3 4 1 2 3 4 0 0 0 0 4 3 2 1 4 1 1 3 4 1 1 2 4 1 1 3 3 2 1 2 4 3 4 0 1 4 3 0 2 4 1 0 0 0 0 2 1 1 2 4 1 3 2 3 0 0
Sample Output
YES NO NO NO NOYES
思路:其实这就是一道模板题bfs,只是需要在此基础上加一个数组用来存储它的转弯次数。如果仅采用最短路的做法来写的话,到最后求得的路径是最短但是不能保证它是小于等于二,所以,最短路的做法在这里是不可取的。
#include<stdio.h> #include<algorithm> #include<iostream> #include<string.h> #include<queue> using namespace std; struct node { int x; int y; int count; //用来表示路径的方向; }s[1005]; int map[1005][1005]; //输入的地图; int set[1005][1005]; //记录到该点的转弯次数; int sx,sy,ex,ey; //分别表示初始位置的x,y坐标和结束位置的x,y坐标; int n,m; int start; //初始位置是的值; int temp; int t; int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}}; node now,nex; int bfs() { queue<node>Q; now.x=sx; now.y=sy; now.count=-1; //我是当一出来他的转弯数就是一,最后判断是否为3就可以了; Q.push(now); set[now.x][now.y]=0; while(!Q.empty()) { now=Q.front(); Q.pop(); for(int i=0;i<4;i++) { nex.x=now.x+dir[i][0]; nex.y=now.y+dir[i][1]; nex.count=i;//i代表方向。0:向下;1:向上;2:向右;3:向左; if(nex.count!=now.count) temp=set[now.x][now.y]+1; else temp=set[now.x][now.y]; if(nex.x<n&&nex.x>=0&&nex.y>=0&&nex.y<m&&(temp<=set[nex.x][nex.y]||set[nex.x][nex.y]==0)) { if(nex.x==ex&&nex.y==ey&&map[nex.x][nex.y]==start) { set[nex.x][nex.y]=temp; if(set[nex.x][nex.y]<=3) return 1; } if(map[nex.x][nex.y]==0) { set[nex.x][nex.y]=temp; if(set[nex.x][nex.y]==4) continue; Q.push(nex); } } } } return 0; } int main() { while(scanf("%d%d",&n,&m),n||m) { int i,j; for(i=0;i<n;i++) for(j=0;j<m;j++) cin>>map[i][j]; cin>>t; for(i=0;i<t;i++) { memset(set,0,sizeof(set)); cin>>sx>>sy>>ex>>ey; //初始的时候是从00开始的,所以坐标都-1了; sx=sx-1; sy=sy-1; ex=ex-1; ey=ey-1; start=map[sx][sy]; if(map[sx][sy]!=map[ex][ey]||map[sx][sy]==0||map[ex][ey]==0) { printf("NO\n"); continue; } if(bfs()) printf("YES\n"); else printf("NO\n"); } } return 0; }