题目
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 0Sample Output
YES
NO
NO
NO
NO
YES
题解
连连看游戏的后台实现
根据我们接触到的练练看游戏,可以确定一下规则:
-
要点击两个不同的位置
-
点击的两个位置应该是合法位置
-
点击的两个位置应该对应的是相应的棋子,并且不能有空白格
-
棋子间路径只能通过空白格,并且最多只能转过两个拐角
如同正常的BFS一样,只是每次拓展路径要拓展一条直线,记录下到该点转过的拐角,拓展3层(两个拐角)
判断目标点是否能到达即可
代码
/* By:OhYee Github:OhYee Email:oyohyee@oyohyee.com Blog:http://www.cnblogs.com/ohyee/ かしこいかわいい? エリーチカ! 要写出来Хорошо的代码哦~ */ #include <cstdio> #include <algorithm> #include <cstring> #include <cmath> #include <string> #include <iostream> #include <vector> #include <list> #include <queue> #include <stack> using namespace std; //DEBUG MODE #define debug 0 //循环 #define REP(n) for(int o=0;o<n;o++) const int maxn = 1005; int m,n; int Map[maxn][maxn]; int dis[maxn][maxn]; typedef pair<int,int> point; int BFS(int s1,int s2,int v1,int v2) { define con1(nn) (nn<=0||nn>n) define con2(mm) (mm<=0||mm>m) //位置错误 if(con1(s1) || con1(v1) || con2(s2) || con2(v2)) return -1; //同一位置 if(s1 == v1 && s2 == v2) return -1; //棋子不同 或 无棋子 if(Map[s1][s2] != Map[v1][v2] || Map[s1][s2]==0) return -1; queue<point> Q; memset(dis,-1,sizeof(dis)); Q.push(point(s1,s2)); dis[s1][s2] = 0; while(!Q.empty()) { int th1 = Q.front().first; int th2 = Q.front().second; Q.pop(); //达到终点 if(th1 == v1 && th2 == v2) break; //拓展节点 define condition \ (next1 > 0 && next1 <= n && next2 > 0 && next2 <= m \ && (Map[next1][next2] == 0||(next1==v1 && next2==v2))) define push \ if(dis[next1][next2]==-1 && dis[th1][th2]<=2) {\ Q.push(point(next1,next2));\ dis[next1][next2] = dis[th1][th2] + 1;\ }\ int next1,next2; for(next1 = th1,next2 = th2 + 1;condition;next2++) { push; } for(next1 = th1 + 1,next2 = th2;condition;next1++) { push; } for(next1 = th1,next2 = th2 - 1;condition;next2--) { push; } for(next1 = th1 - 1,next2 = th2;condition;next1--) { push; } } return dis[v1][v2]; } bool Do() { if(scanf("%d%d",&n,&m),n == 0 && m == 0) return false; for(int i = 1;i <= n;i++) for(int j = 1;j <= m;j++) scanf("%d",&Map[i][j]); int T; scanf("%d",&T); while(T--) { int s1,s2,v1,v2; scanf("%d%d%d%d",&s1,&s2,&v1,&v2); printf("%s\n",BFS(s1,s2,v1,v2)==-1?"NO":"YES"); } return true; } int main() { while(Do()); return 0; }