http://acm.hdu.edu.cn/showproblem.php?pid=1175
这题是1728逃离迷宫的简化版本,也是要找到转弯最少的那个路径。。。不过这题还要将不一样的棋子的连法,及要连接的棋子中存在0的连法删割掉,直接输出NO
#include<stdio.h> #include<stdlib.h> #include<string.h> #define T 2 int hash[1000][1000],vis[1000][1000]; int n,m,sx,sy,ex,ey,temp; int dir[4][2]={{1,0},{-1,0},{0,1},{0,-1}}; struct node { int x,y,k;//保存坐标和转弯数 }s[1000000]; int pd(int x,int y)//判断是否越界,没越界就返回1 { return (x>=0&&x<n&&y>=0&&y<m); } int bfs() { int head,tail,i,a,b; struct node next,x; head=tail=0; s[head].x=sx; s[head].y=sy; s[head].k=-1;//下面会加一,所以这里赋为-1 while(head<=tail) { next=s[head++]; if(next.k>T) continue;; if(next.x==ex&&next.y==ey&&next.k<=T) return 1; x.k=next.k+1;//上次走完了一个方向上的所有的点,所有这次肯定会转弯 for(i=0;i<4;i++) { a=next.x+dir[i][0]; b=next.y+dir[i][1]; while(pd(a,b)&&hash[a][b]==0) { if(!vis[a][b]) { x.x=a; x.y=b; s[++tail]=x; vis[a][b]=1; if(x.x==ex&&x.y==ey) if(x.k<=T){return 1;} else return 0; } a+=dir[i][0]; b+=dir[i][1]; } } } return 0; } int main() { int i,j,q; while(scanf("%d%d",&n,&m),m||n) { for(i=0;i<n;i++) for(j=0;j<m;j++) { scanf("%d",&hash[i][j]); //vis[i][j]=hash[i][j]?1:0; } scanf("%d",&q); while(q--) { memset(vis,0,sizeof(vis)); scanf("%d%d%d%d",&sx,&sy,&ex,&ey); sx--; sy--; ex--; ey--; if(hash[sx][sy]!=hash[ex][ey]||hash[sx][sy]==0) { printf("NO "); continue; } temp=hash[ex][ey]; hash[ex][ey]=0; if(bfs()) printf("YES "); else printf("NO "); hash[ex][ey]=temp; } } return 0; }