• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
FightingForWorldFinal
博客园    首页    新随笔    联系   管理    订阅  订阅

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 }
View Code

 再加一个自己写的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 }
View Code

 

posted @ 2013-07-17 13:09  Sky-J  阅读(402)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3