HDU1175连连看 广度优先搜索BFS
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cmath> 5 #include <cstdlib> 6 #include <algorithm> 7 #include <vector> 8 #include <stack> 9 #include <queue> 10 #include <cassert> 11 #include <set> 12 #include <sstream> 13 #include <map> 14 using namespace std ; 15 #ifdef DeBUG 16 #define bug assert 17 #else 18 #define bug // 19 #endif 20 #define zero {0} 21 int direc[4][2]={0,1,0,-1,1,0,-1,0};//方向依次定义为右左下上 22 int a[1005][1005],visited[1005][1005],m,n; 23 //a为输入的2维向量,visited记录该点是否被访问过,同时记录转折次数, 24 //如果新的转折次数小于以前访问时的次数那么更新,否则不更新。 25 struct node 26 { 27 int x;//行数 28 int y;//列数 29 int dir;//方向 30 int corner;//转角次数 31 }; 32 node start,end;//开始和结束 33 void bfs()//宽度搜索 34 { 35 queue<node>q; 36 node cur,pre;//用来记录当前节点和前一个进行比较 37 start.dir=-1;//开始时无方向 38 start.corner=0;//开始时转角次数为0 39 q.push(start); 40 while(!q.empty()) 41 { 42 pre=q.front(); 43 q.pop(); 44 if(pre.x==end.x&&pre.y==end.y) 45 { 46 cout<<"YES"<<endl; 47 return ; 48 } 49 for(int i=0;i<4;i++)//对转交四个方向分别进行判断 50 { 51 cur.x=pre.x+direc[i][0]; 52 cur.y=pre.y+direc[i][1]; 53 cur.corner=pre.corner;//令当前转角次数和前一个相同 54 cur.dir=i;//当前方向 55 if(pre.dir!=i&&pre.dir!=-1)cur.corner++;//前一个不是开始点,且当前方向与之前不一致转角++ 56 if(cur.x<1||cur.y<1||cur.x>n||cur.y>m||cur.corner>2) 57 continue;//出界和超限制的不要 58 if(a[cur.x][cur.y]&&!(cur.x==end.x&&cur.y==end.y)) 59 continue;//当前不是终点但有数字,结束 60 if(cur.corner<visited[cur.x][cur.y]) 61 { 62 visited[cur.x][cur.y]=cur.corner; 63 q.push(cur); 64 } 65 } 66 } 67 cout<<"NO"<<endl; 68 } 69 int main() 70 { 71 #ifdef DeBUG 72 freopen("C:\\Users\\Sky\\Desktop\\1.in","r",stdin); 73 #endif 74 int q; 75 while(scanf("%d%d",&n,&m),n,m) 76 { 77 for(int i=1;i<=n;i++) 78 for(int j=1;j<=m;j++) 79 scanf("%d",&a[i][j]); 80 scanf("%d",&q); 81 while(q--) 82 { 83 scanf("%d%d%d%d",&start.x,&start.y,&end.x,&end.y); 84 if(start.x==end.x&&start.y==end.y)//开始结束在同一个位置 85 { 86 cout<<"NO"<<endl;continue; 87 } 88 if(!a[start.x][start.y]||!a[end.x][end.y]||(a[start.x][start.y]!=a[end.x][end.y])) 89 { 90 cout<<"NO"<<endl; 91 continue;//开始结束位置没有数字或者开始和结束位置不等 92 } 93 for(int i=1;i<=n;i++) 94 for(int j=1;j<=m;j++) 95 visited[i][j]=INT_MAX; 96 bfs(); 97 } 98 } 99 100 return 0; 101 }
再加一个自己写的bfs
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <cstdlib> 5 #include <algorithm> 6 #include <vector> 7 #include <stack> 8 #include <queue> 9 #include <cassert> 10 #include <set> 11 #include <sstream> 12 #include <map> 13 using namespace std ; 14 #ifdef DeBUG 15 #define bug assert 16 #else 17 #define bug // 18 #endif 19 #define zero {0} 20 #define MAXNUM 99999999 21 int dir[4][2]={0,1,0,-1,1,0,-1,0}; 22 int n,m; 23 int i,j,k; 24 int _flag=0; 25 int xs,ys,x2,y2; 26 int a[1001][1001]=zero; 27 int visited[1001][1001]=zero; 28 void dfs(int x,int y,int di) 29 { 30 if(_flag) 31 return; 32 if (x !=x2 && y != y2 && visited[x][y] == 2)//别看就这两行,效率提高的不是一点两点,去掉后4234msA,加上140ms 33 return ;//横纵坐标都不一样说明还得再转,但是已不能转 34 if(visited[x][y]>2)//转弯多了 35 return ; 36 if(visited[x][y]<=2&&x==x2&&y==y2)//成功 37 { 38 _flag=1; 39 return; 40 } 41 for(int i=0;i<4;i++) 42 { 43 int tx=x+dir[i][0]; 44 int ty=y+dir[i][1]; 45 if(tx<=0||ty<=0||tx>n||ty>m)//出界剪枝 46 continue; 47 if(visited[tx][ty]<visited[x][y])//下一步要走的弯数小了似乎都要剪掉 48 continue; 49 if((di!=i&&di!=-1)&&visited[tx][ty]<visited[x][y]+1)//有转弯情况时,原因同上 50 continue; 51 if((a[tx][ty]!=0&&(tx!=x2||ty!=y2))||(a[tx][ty]!=0&&(tx!=x2||ty!=y2))) 52 continue;//下一步不是0,不能联通,但此点不是终点或始点,逻辑问题绕我半天 53 visited[tx][ty]=visited[x][y];//下步的弯数 54 if(di!=i&&di!=-1)//有转弯情况加上 55 visited[tx][ty]++; 56 dfs(tx,ty,i);//搜 57 if(_flag)//还是剪枝 58 return; 59 // visited[tx][ty]=MAXNUM;//这样可以把失败时的visited复原,类似8皇后 60 } 61 } 62 int main() 63 { 64 #ifdef DeBUG 65 freopen("C:\\Users\\Sky\\Desktop\\1.in","r",stdin); 66 #endif 67 68 69 while(scanf("%d%d",&n,&m),n!=0&&m!=0) 70 { 71 memset(a,0,sizeof(a)); 72 for(i=1;i<=n;i++) 73 { 74 for(j=1;j<=m;j++) 75 { 76 scanf("%d",&a[i][j]); 77 } 78 } 79 int T; 80 81 scanf("%d",&T); 82 while(T--) 83 { 84 _flag=0; 85 for(i=1;i<=n;i++) 86 { 87 for(j=1;j<=m;j++) 88 { 89 visited[i][j]=MAXNUM; 90 } 91 } 92 scanf("%d%d%d%d",&xs,&ys,&x2,&y2); 93 if(a[xs][ys]!=a[x2][y2]||(xs==x2&&ys==y2)||!a[xs][ys]||!a[x2][y2]) 94 { 95 printf("NO\n"); 96 continue;//剪枝,你懂得 97 } 98 visited[xs][ys]=0; 99 dfs(xs,ys,-1); 100 if(_flag) 101 printf("YES\n"); 102 else 103 printf("NO\n"); 104 } 105 } 106 return 0; 107 }