原题链接:http://acm.hdu.edu.cn/showproblem.php?pid=1175
连连看
Time Limit: 20000/10000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 23190 Accepted Submission(s): 5718
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 NO YES
之前用DFS写了一次,内存超了。于是用BFS重写了一次。
注意满足条件的判断,这个稍微有一点复杂。应该有初始情况两个数不相等的情况。
注意题目要求“线的转折次数不超过两次”,我没有算转折点,我算的折线数目。(≤3)
1 #include <stdio.h> 2 #include <string.h> 3 #include <queue> 4 #include <iostream> 5 using namespace std; 6 int n, m, s; 7 int map[1002][1002]; 8 int vis[1002][1002]; 9 int x1, y1, x2, y2; 10 int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; 11 typedef struct Position 12 { 13 int x, y; 14 int count; 15 }Position; 16 17 int BFS() 18 { 19 queue<Position> q; 20 Position fst, tmp; 21 fst.x = x1; 22 fst.y = y1; 23 fst.count = -1; //init. first one not calculate. 24 q.push(fst); 25 vis[x1][y1] = 0; 26 int sum; 27 while(!q.empty()) 28 { 29 fst = q.front(); 30 q.pop(); 31 for(int i = 0; i < 4; i++) 32 { 33 tmp.x = fst.x + dir[i][0]; 34 tmp.y = fst.y + dir[i][1]; 35 if(fst.count == i) 36 { 37 sum = vis[fst.x][fst.y]; 38 } 39 else 40 { 41 sum = vis[fst.x][fst.y] + 1; 42 } 43 tmp.count = i; 44 if( tmp.x >= 0 && 45 tmp.x < n && 46 tmp.y >= 0 && 47 tmp.y < m && 48 (vis[tmp.x][tmp.y] == 0 || sum <= vis[tmp.x][tmp.y])) 49 { 50 vis[tmp.x][tmp.y] = sum; 51 if(tmp.x == x2 && tmp.y == y2) 52 { 53 if(vis[tmp.x][tmp.y] <= 3) 54 { 55 return 1; 56 } 57 } 58 if(vis[tmp.x][tmp.y] > 3) 59 { 60 continue; 61 } 62 if(map[tmp.x][tmp.y] == 0) 63 { 64 q.push(tmp); 65 } 66 } 67 } 68 } 69 return 0; 70 } 71 72 73 int main() 74 { 75 while(scanf("%d%d",&n,&m) != EOF && n+m) 76 { 77 for(int i = 0; i < n; i++) 78 { 79 for(int j = 0; j < m; j++) 80 { 81 scanf("%d", &map[i][j]); 82 } 83 } 84 scanf("%d", &s); 85 for(int i = 0 ; i < s; i++) 86 { 87 scanf("%d %d %d %d", &x1, &y1, &x2, &y2); 88 x1--; 89 x2--; 90 y1--; 91 y2--; 92 if((map[x1][y1] != map[x2][y2]) || 93 map[x1][y1] == 0 || 94 map[x2][y2] == 0 || 95 (x1==x2&&y1==y2)) 96 { 97 printf("NO "); 98 continue; 99 } 100 memset(vis, 0, sizeof(vis)); 101 if(BFS()) 102 { 103 printf("YES "); 104 } 105 else 106 { 107 printf("NO "); 108 } 109 } 110 111 } 112 return 0; 113 }