dfs搜索tempter of the bone(hdu 1010)

http://acm.hdu.edu.cn/showproblem.php?pid=1010

题目本身不难,但是不剪枝肯定会超时,还有很多细节要注意,希望能够通过更多的训练加强自己这一方面的能力,使细致成为习惯

 1 #include<iostream>
 2 #include<cstring>
 3 using namespace std;
 4 #define M 100
 5 #define mem0(f) memset(f,0,sizeof(f))
 6 char s[M][M];
 7 int n,m,t;//还要把访问的都给标记一下,不能回走的
 8 //int ts;//花掉的时间
 9 int ok;//ok用来判断是否可以逃生
10 int abs(int a)
11 {
12     if(a>0)return a;
13     return -a;
14 }
15 char bj[M][M];
16 void dfs(int x,int y,int ts)
17 {
18     if(x<0||y<0||x>=n||y>=m||s[x][y]=='X'||ok==1||bj[x][y]==1||ts>t)
19     return;
20     if(s[x][y]=='D'&&ts==t)ok=1;
21     bj[x][y]=1;
22     if(ok!=1)
23     {
24     dfs(x,y+1,ts+1);
25     dfs(x,y-1,ts+1);
26     dfs(x-1,y,ts+1);
27     dfs(x+1,y,ts+1);
28     bj[x][y]=0;//此路不通
29     }
30 }
31 int main()
32 {
33     int x1,y1,x2,y2;
34     int test;
35     while(cin>>n>>m>>t)
36     {
37         ok=0;
38         mem0(s);
39         mem0(bj);
40         if(!n&&!m&&!t)break;
41         for(int i=0;i<n;i++)
42             for(int k=0;k<m;k++)
43         {
44             cin>>s[i][k];
45             if(s[i][k]=='S'){x1=i;y1=k;}
46             if(s[i][k]=='D'){x2=i;y2=k;}
47         }
48         //剪枝
49         test=t-abs(x2-x1)-abs(y2-y1);//擦 啊 擦  ,竟然忘记了取绝对值,晕死,果然是水平太低
50         if(test<0)ok=0;
51         else if(test%2)ok=0;
52         else{
53         for(int i=0;i<n;i++)
54             for(int k=0;k<m;k++)
55         {
56             if(s[i][k]=='S')
57             {
58                 dfs(i,k,0);
59                 i=n+1;
60                 break;
61             }
62         }}
63         if(ok==1)cout<<"YES
";
64         else cout<<"NO
";
65     }
66     return 0;
67 }
68 //这个题目的核心代码算是出来了,但是要是不剪枝的话,肯定超时
69 /*考虑到时间限制,
70 1,最短时间小于t则不可能
71 2,时间有多,多的时间不是2的倍数也不可能*/
View Code

如果考虑到走过的点不能再走, biaoji这个数组其实可以不开,只需要把走过的点标记为“X”就行,走不通的话,重新标记为“.”,这样的话在存储上又会有一点优化。

原文地址:https://www.cnblogs.com/plank-george-zzo/p/3206730.html