• hdu1175 连连看(bfs疯狂MLE和T,遂考虑dfs+剪枝)


    题目链接:http://icpc.njust.edu.cn/Problem/Hdu/1175/

    题目大意就是给出地图,上面有若干的数,相当于连连看,给了q个查询,问给出的两个位置的数能否在两次转弯以内划线消除。dfs即可解决,要记录路径,防止往回走,此外就是剪枝了,如果已经转过了两次弯但是跟终点的横坐标和纵坐标都不在同一条直线上说明终点在本次搜索中是无法到达的。还有就是只要有目标状态就全部回溯到调用者.

    代码如下:

     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 typedef unsigned int ui;
     4 typedef long long ll;
     5 typedef unsigned long long ull;
     6 #define pf printf
     7 #define mem(a,b) memset(a,b,sizeof(a))
     8 #define prime1 1e9+7
     9 #define prime2 1e9+9
    10 #define pi 3.14159265
    11 #define lson l,mid,rt<<1
    12 #define rson mid+1,r,rt<<1|1
    13 #define scand(x) scanf("%llf",&x) 
    14 #define f(i,a,b) for(int i=a;i<=b;i++)
    15 #define scan(a) scanf("%d",&a)
    16 #define dbg(args) cout<<#args<<":"<<args<<endl;
    17 #define inf 0x3f3f3f3f
    18 #define maxn 1005
    19 int n,m,t;
    20 int Map[maxn][maxn];
    21 int xa,ya,xb,yb;
    22 int dir[][2]={0,1,0,-1,1,0,-1,0};
    23 bool vis[maxn][maxn];
    24 bool flag;
    25 void dfs(int x,int y,int d,int turn)//d存放的是方向信息 
    26 {
    27     if(turn>2||flag)return;//只要找到目标状态就全部回溯到最初调用者
    28     if(turn==2&&(x-xb)&&(y-yb))return;
    29     //如果已经转过两次弯但是和终点不在一条线上说明不可能搜索到目标状态,剪枝 
    30     if(x==xb&&y==yb&&turn<=2)
    31     {
    32         flag=true;
    33         return;
    34      }
    35     f(i,0,3)
    36     {
    37         int xx=x+dir[i][0];
    38         int yy=y+dir[i][1];
    39         if(xx<1||xx>n||yy<1||yy>m||vis[xx][yy])continue;
    40         if((Map[xx][yy]==0)||(xx==xb&&yy==yb))
    41         {
    42             vis[xx][yy]=1;
    43             //设置访问记录使得本轮深度搜索记住来时的路,避免下一次扩展的时候在再次走上老路,错误计数 
    44             if(d==-1||d!=i)//没有访问过的位置而且方向发生变化那么一定是转过弯的 
    45             {
    46 //                cout<<"xx:"<<xx<<" yy:"<<yy<<" turn:"<<turn<<endl;
    47                 dfs(xx,yy,i,turn+1);
    48             }
    49             else 
    50                 dfs(xx,yy,i,turn);
    51             vis[xx][yy]=0;//回溯 
    52         }
    53      } 
    54 }
    55 int main()
    56 {
    57     //freopen("input.txt","r",stdin);
    58     //freopen("output.txt","w",stdout);
    59     std::ios::sync_with_stdio(false);
    60     while(scanf("%d%d",&n,&m)==2&&!(n==0&&m==0))
    61     {
    62         f(i,1,n)
    63             f(j,1,m)
    64             {
    65                 scan(Map[i][j]);
    66             }
    67             scan(t);
    68             while(t--)
    69             {
    70                 flag=false; 
    71                 scanf("%d%d%d%d",&xa,&ya,&xb,&yb);
    72                 //预处理不可行的状态, 
    73                 if((Map[xa][ya]*Map[xb][yb]==0)||(Map[xa][ya]!=Map[xb][yb])||(xa==xb&&ya==yb))pf("NO
    ");
    74                 else
    75                 {
    76                     mem(vis,false);
    77                     vis[xa][ya]=1;
    78                     dfs(xa,ya,-1,-1);//初始方向设为-1使得与四个搜索方向都不同,turn必然加一 
    79                     if(flag)pf("YES
    ");
    80                     else pf("NO
    ");
    81                 }
    82             }
    83             
    84     }
    85  } 
  • 相关阅读:
    Lua Coroutine详解
    Lua IO库详解
    vue 组件基本使用
    js 发送异步请求
    小程序保存图片到相册
    js 学习四 对象应用 吃货游戏
    js 学习三 Array
    js 学习二 字符串常用方法
    js 学习一 猜数字游戏
    phpmyadmin导入大容量.sql文件
  • 原文地址:https://www.cnblogs.com/randy-lo/p/12510485.html
Copyright © 2020-2023  润新知