hdu 1172 连连看
连连看
要求:
如果某两个相同的棋子,可以通过一条线连起来(这条线不能经过其它棋子),而且线的转折次数不超过两次,那么这两个棋子就可以在棋盘上消去。注意:连线不能从外围绕过。0表示没有棋子
还是老毛病,没看清题就开始做了,一直WA,上网看了别人的代码,发现有条件f[x][y]==0
才注意到,0表示没有棋子,连线只能通过没有棋子的地方连线。其他思路跟hdu1728 逃离迷宫思路差不多,都是要考虑转弯数,不能对点进行标记,并且从起点到终点要找最小的转弯数存入a[x][y],这样对于每个进队出队的点的转弯数都小于题目要求的最大转弯数,提高了效率,这题与逃离迷宫不同点在于判定条件都是在f[x][y]==0下进行连线的,所以每一个进队的点都必须满足(f[x][y]=0||(x==cx&&y==cy))
额,代码太弱了,1250MS……
以后一定要改掉这个不细心的毛病……
1 #include<stdio.h> 2 #include<string.h> 3 #include<queue> 4 using namespace std; 5 int a[1005][1005],f[1005][1005]; 6 struct node 7 { 8 int x,y; 9 int flag; 10 int count; 11 }; 12 int n,m; 13 int d[4][2]={0,1,0,-1,1,0,-1,0}; 14 int judge(int x,int y) 15 { 16 if(x>=1&&x<=n&&y>=1&&y<=m) 17 return 1; 18 return 0; 19 } 20 int bfs(int x,int y,int cx,int cy) 21 { 22 int i; 23 queue<node>q; 24 node cur,next; 25 cur.x=x; 26 cur.y=y; 27 cur.flag=-1; 28 cur.count=0; 29 q.push(cur); 30 a[x][y]=0; 31 while(!q.empty()) 32 { 33 cur=q.front(); 34 q.pop(); 35 if(cur.count>2) 36 return 0; 37 for(i=0;i<4;i++) 38 { 39 next.x=cur.x+d[i][0]; 40 next.y=cur.y+d[i][1]; 41 if(judge(next.x,next.y)) 42 { 43 if(cur.flag==-1||i==cur.flag) 44 { 45 next.flag=i; 46 next.count=cur.count; 47 } 48 if(cur.flag!=-1&&i!=cur.flag) 49 { 50 next.flag=i; 51 next.count=cur.count+1; 52 } 53 54 if((a[next.x][next.y]>=next.count)&&(next.count<=2)) 55 { 56 if(f[next.x][next.y]==0||next.x==cx&&next.y==cy) 57 { 58 a[next.x][next.y]=next.count; 59 if(next.x==cx&&next.y==cy) 60 return 1; 61 62 q.push(next); 63 } 64 } 65 } 66 } 67 } 68 return 0; 69 } 70 int main() 71 { 72 int i,j,sx,sy,cx,cy; 73 int t; 74 while(scanf("%d%d",&n,&m),n!=0||m!=0) 75 { 76 for(i=1;i<=n;i++) 77 for(j=1;j<=m;j++) 78 { 79 scanf("%d",&f[i][j]); 80 } 81 scanf("%d",&t); 82 for(i=1;i<=t;i++) 83 { 84 scanf("%d%d%d%d",&sx,&sy,&cx,&cy); 85 if(f[sx][sy]!=f[cx][cy]||f[sx][sy]==0||f[cx][cy]==0||(sx==cx&&sy==cy)) 86 { 87 printf("NO\n"); 88 continue; 89 } 90 else 91 { 92 memset(a,9,sizeof(a)); 93 if(bfs(sx,sy,cx,cy)) 94 printf("YES\n"); 95 else 96 printf("NO\n"); 97 } 98 } 99 } 100 return 0; 101 }