zoukankan      html  css  js  c++  java
  • 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
    ");
     96                 continue;//剪枝,你懂得 
     97             }
     98             visited[xs][ys]=0;
     99             dfs(xs,ys,-1);
    100             if(_flag)
    101             printf("YES
    ");
    102             else
    103             printf("NO
    ");
    104         }
    105     }
    106     return 0;
    107 }
    View Code
  • 相关阅读:
    js异步编程
    gitreset
    js数据类型
    vuex报错
    个人管理系统综述
    ffmpeg第7篇:数据流选择神器map指令
    eltable多选框根据条件隐藏显示
    [域渗透内网渗透] 从 web 到域控,你未曾设想的攻击链
    宽字节第二期线下培训开始招生啦!!!
    cve20212394 weblogic反序列化漏洞分析
  • 原文地址:https://www.cnblogs.com/Skyxj/p/3195601.html
Copyright © 2011-2022 走看看