HDOJ 1010
深度搜索,注意要剪枝
1.奇偶剪枝
可以把map看成这样:
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
1 0 1 0 1 0
0 1 0 1 0 1
从为 0 的格子走一步,必然走向为 1 的格子
从为 1 的格子走一步,必然走向为 0 的格子
即:
0 ->1或1->0 必然是奇数步
0->0 走1->1 必然是偶数步
则如果((di-si+dj-sj)&1)!=(t&1) 就可以直接输出“NO”了
2.判断可走的block是否小于时间总数
n*m-wall<=t 就输出“NO”
1 #include <iostream> 2 #include <stdio.h> 3 using namespace std; 4 5 char map[10][10]; 6 int desc[4][2]={{-1,0},{1,0},{0,1},{0,-1}}; 7 int si,sj,di,dj; 8 int n,m,t; 9 int escape; 10 11 void dfs(int ni,int nj,int nt) 12 { 13 if(escape) return; 14 if(nt>t) return; 15 else if(nt==t) 16 { 17 if(ni==di && nj==dj) 18 { 19 printf("YES\n"); 20 escape=1; 21 } 22 return; 23 } 24 else 25 { 26 for(int k=0;k<4;++k) 27 { 28 if(ni+desc[k][0]>-1&&ni+desc[k][0]<n && nj+desc[k][1]>-1&&nj+desc[k][1]<m) 29 { 30 if(map[ni+desc[k][0]][nj+desc[k][1]]!='X') 31 { 32 map[ni][nj]='X'; 33 //printf("goto (%d,%d) %d\n",ni+desc[k][0],nj+desc[k][1],nt+1); 34 dfs(ni+desc[k][0],nj+desc[k][1],nt+1); 35 map[ni][nj]='.'; 36 } 37 } 38 } 39 } 40 } 41 42 int main() 43 { 44 int i,j,wall; 45 46 while(scanf("%d %d %d",&n,&m,&t),n||m||t) 47 { 48 escape=0; 49 di=10; 50 dj=10; 51 wall=0; 52 getchar(); 53 for(i=0;i<n;++i) 54 { 55 for(j=0;j<m;++j) 56 { 57 //scanf("%c",&map[i][j]); 58 cin>>map[i][j]; 59 if(map[i][j]=='S') 60 { 61 si=i; 62 sj=j; 63 } 64 else if(map[i][j]=='D') 65 { 66 di=i; 67 dj=j; 68 } 69 else if(map[i][j]=='X') ++wall; 70 } 71 //getchar(); 72 } 73 74 //前半句是判断可以走的block数是否小于等于时间; 75 //后半句是奇偶剪枝 76 if(n*m-wall<=t || ((di-si+dj-sj)&1)!=(t&1)) 77 { 78 printf("NO\n"); 79 continue; 80 } 81 dfs(si,sj,0); 82 if(escape==0) printf("NO\n"); 83 } 84 }
浙公网安备 33010602011771号