Tempter of the Bone------剪枝

看了好多别人的  代码,最终还是 感觉 这种代码的风格适合我  下面附上代码   

 1 /* 首先 应该充满信心!  先写出来 自己的程序  然后慢慢改 ,
 2    如果是 答题思路错误的话 借鉴别人的 代码 再写
 3 */
 4 /*没有剪枝  时间超限*/
 5 #include<stdio.h>
 6 #include<string.h>
 7 char a[10][10];
 8 int visited[10][10];
 9 int s[4][2]={-1,0,1,0,0,-1,0,1};
10 int n,m,t,bx,by,cx,cy,step=0,mark;
11 void DFS(int y,int x,int step)      //  传输 进去现在 的  位置 并且传出过去 已有的 步数
12 {
13     if(y==cy&&x==cx&&step==t)
14     {
15         mark=1;
16     }
17     visited[y][x]=1;
18     for(int i=0;i<4;i++)
19     {
20         if(a[y+s[i][0]][x+s[i][1]]!='X'&&(y+s[i][0])>=0&&(y+s[i][0])<n&&(x+s[i][1])>=0&&(x+s[i][1])<m&&!visited[y+s[i][0]][x+s[i][1]])  //  不超界  并且   不是墙 而且没有访问
21         {
22             step++;
23             DFS(y+s[i][0],x+s[i][1],step);
24             step--;
25         }
26 
27     }
28     visited[y][x]=0;
29 }
30 int main()
31 {
32     int i,j;
33     while(scanf("%d%d%d",&n,&m,&t)!=EOF)
34     {
35         if(n==0&&m==0&&t==0)
36             break
37         getchar();
38         memset(visited,0,sizeof(visited));
39         for(mark=step=i=0;i<n;i++)
40         {
41             for(j=0;j<m;j++)
42             {
43                 scanf("%c",&a[i][j]);
44                 if(a[i][j]=='S')   // 找到进入的坐标
45                 {
46                     bx=j;
47                     by=i;
48                 }
49                 if(a[i][j]=='D')   // 找到出去的坐标
50                 {
51                     cx=j;
52                     cy=i;
53                 }
54             }
55             getchar();
56         }
57         DFS(by,bx,0);    // 传输 当前座标
58         if(mark!=1)
59             printf("NO
");
60         else
61             printf("YES
");
62     }
63     return 0;
64 }

上面的 没有剪枝  时间超限   下面开始 剪枝  .

 1 /* 首先 应该充满信心!  先写出来 自己的程序  然后慢慢改 , 如果是 答题思路错误的话 借鉴别人的 代码 再写  */
 2 /*
 3         剪枝:
 4                 1:  奇偶剪枝:到终点的最短步数(就算需要绕路也没事要的奇偶)  和  到终点限定的步数  如果 奇偶性不同的话是不可能达到的  (绕路是同时多出偶数倍的步数)  1/2 的时间
 5                 2:  进去的时候  到 终点的最短路 如果大于  给定的步数  也不可能   .   (也可能绕路绕超所以需要重复)
 6                 3:  可以走的格子 走完但是仍然还不够限定的步数  就不行了
 7 */
 8 #include<stdio.h>
 9 #include<string.h>
10 #include<math.h>
11 #include<iostream>
12 #include<algorithm>
13 #include<queue>
14 #include<vector>
15 #include<set>
16 #include<stack>
17 #include<string>
18 #include<sstream>
19 #include<map>
20 #include<cctype>
21 #include<limits.h>
22 #define leng 10
23 using namespace std;
24 char a[leng][leng];
25 int ex,ey,n,m,t,bx,mark,by,b[4][2]={0,1,1,0,0,-1,-1,0},visited[leng][leng];
26 void DFS(int y,int x,int step)
27 {
28     int d=t-step-abs(y-ey)-abs(x-ex);   // 剩下 的步数   -   到终点的步数  小于 0 完蛋 .
29     if(t<step||mark==1||d<0||d%2)   // 这里三个 剪枝 .   上述公式 如果不是 偶数的话 , 就完蛋.
30         return;
31     if(a[y][x]=='D'&&t==step)
32     {
33         mark=1;
34     }
35     visited[y][x]=1;
36     for(int i=0;i<4;i++)
37     {
38         int tx=x+b[i][0],ty=y+b[i][1];
39         if(a[ty][tx]!='X'&&tx>=0&&tx<m&&ty>=0&&ty<n&&!visited[ty][tx]) // 不是 墙  不超界  没用过
40         {
41             DFS(ty,tx,step+1);
42         }
43     }
44     visited[y][x]=0;
45 }
46 int main()
47 {
48     while(scanf("%d%d%d",&n,&m,&t),!(n==m&&m==t&&t==0))
49     {
50         for(int i=0;i<n;i++)
51         {
52             for(int j=0;j<m;j++)
53             {
54                 scanf(" %c",&a[i][j]);
55                 if(a[i][j]=='S')
56                 {
57                     bx=j;
58                     by=i;
59                 }
60                 if(a[i][j]=='D')
61                 {
62                     ex=j;
63                     ey=i;
64                 }
65             }
66         }
67         memset(visited,0,sizeof(visited));
68         mark=0;
69         DFS(by,bx,0);
70         if(mark==0)
71             printf("NO
");
72         else
73             printf("YES
");
74     }
75     return 0;
76 }
原文地址:https://www.cnblogs.com/A-FM/p/5259760.html