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\n"); 60 else 61 printf("YES\n"); 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\n"); 72 else 73 printf("YES\n"); 74 } 75 return 0; 76 }