http://acm.hdu.edu.cn/showproblem.php?pid=1010
用到了奇偶剪枝:
0 1 0 1
1 0 1 0 如图,设起点为s,终点为e,s->e的最短步数为t. sum=t+extra. [因为extra无论怎么走,最终都要返回其中一条最短路径上,即有来回,所以extra=2*某个数,一定是偶数。
0 1 0 1
1 0 1 0
【所以此题中,v-step表示还可以走多少步,abs(x-x2)+abs(y-y2)为此刻点到终点位置,由上面剪枝分析,两者之差一定为偶数。所以根据小学数学,奇-奇=偶,偶-偶=偶,可知两数奇偶性相同(有用吗)】
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<cstdio> 2 #include<cmath> 3 #include<cstring> 4 #include<iostream> 5 #include<algorithm> 6 using namespace std; 7 #define mem(a) memset(a,0,sizeof(a)) 8 #define ll long long 9 int fa[4][2]={{0,1},{0,-1},{1,0},{-1,0}}; 10 int n,m,v; 11 char mo[10][10]; 12 int mark[10][10]; 13 int ans,x1,x2,y3,y2; 14 int coun; 15 int abs(int a) 16 { 17 if (a<0) return -a; 18 return a; 19 } 20 void dfs(int x,int y,int step) 21 { 22 if(ans) return ; 23 if(x==x2&&y==y2&&step==v) {ans=1;return ;} 24 int v1=v-step-(abs(x-x2)+abs(y-y2)); 25 if(v1<0||v1&1) 26 return ; 27 for(int i=0;i<4;i++) 28 { 29 int xx=x+fa[i][0]; 30 int yy=y+fa[i][1]; 31 if(xx>=0&&xx<n&&yy>=0&&yy<m&&mark[xx][yy]==0&&mo[xx][yy]!='X') 32 { 33 mark[xx][yy]=1; 34 dfs(xx,yy,step+1); 35 if(ans) return ; 36 mark[xx][yy]=0; 37 } 38 } 39 return ; 40 } 41 int main() 42 { 43 while(~scanf("%d%d%d",&n,&m,&v)&&(n||m||v)) 44 { 45 ans=coun=0; 46 mem(mark); 47 for(int i=0;i<n;i++) 48 scanf("%s",mo[i]); 49 for(int i=0;i<n;i++) 50 { 51 for(int j=0;j<m;j++) 52 { 53 if(mo[i][j]=='S') 54 {x1=i;y3=j;} 55 if(mo[i][j]=='D') 56 {x2=i;y2=j;} 57 if(mo[i][j]=='X') 58 coun++; 59 } 60 } 61 if(v>n*m-coun-1) 62 { 63 printf("NO "); 64 continue; 65 } 66 mark[x1][y3]=1; 67 dfs(x1,y3,0); 68 if(ans==1)printf("YES "); 69 else printf("NO "); 70 } 71 return 0; 72 }