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\n");
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\n");
80                     else pf("NO\n");
81                 }
82             }
83             
84     }
85  } 

 

posted @ 2020-03-17 14:26  WA自动机~  阅读(159)  评论(0编辑  收藏  举报