HDU 1010Tempter of the Bone(奇偶剪枝回溯dfs)
4 4 5S.X...X...XD....3 4 5S.X...X....D0 0 0
NOYES
#include<iostream>#include<cstring>#include<string>#include<cmath>#include<cstdio>using namespace std;char a[10][10];int visi[10][10];int n,m,sum,flag;struct node{ int x; int y;};node sta,en; //起点与终点int dir[4][2]= //四个方向{ {-1,0},{1,0},{0,-1},{0,1}};void dfs(int cx,int cy,int step){ int i; if(flag==1) return; //找到解 if(step==sum) { if(cx==en.x&&cy==en.y) flag=1; return; } int need=abs(cx-en.x)+abs(cy-en.y); int tmp=sum-step; if((tmp%2==0&&need%2==1)||(need%2==0&&tmp%2==1)||tmp<need) //奇偶剪枝 return; for(i=0;i<4;i++) { int px,py; px=cx+dir[i][0],py=cy+dir[i][1]; if(px>=0&&px<n&&py>=0&&py<m&&(a[px][py]=='.'||a[px][py]=='D')&&!visi[px][py]) { visi[px][py]=1; dfs(px,py,step+1); visi[px][py]=0; //回溯 } } //return;}int main(){ int i,j; while(scanf("%d%d%d",&n,&m,&sum)) { if(n==0&&m==0&&sum==0) break; for(i=0;i<n;i++) scanf("%s",a[i]); flag=0; for(i=0;i<n;i++) //找起点 { for(j=0;j<m;j++) { if(a[i][j]=='S') { sta.x=i; sta.y=j; flag=1; break; } } if(flag) break; } flag=0; for(i=0;i<n;i++) //找终点 { for(j=0;j<m;j++) { if(a[i][j]=='D') { en.x=i; en.y=j; flag=1; break; } } if(flag) break; } flag=0; memset(visi,0,sizeof(visi)); visi[sta.x][sta.y]=1; dfs(sta.x,sta.y,0); if(flag) puts("YES"); else puts("NO"); } return 0;}//703MS 228K