题目链接:HDU 1010 Tempter of the Bone
给出一张图,求从S开始走刚好T步能不能到到达D。
奇偶剪枝:t-[abs(ex-sx)+abs(ey-sy)] %2为奇数则不能到达,反之可到达。[abs(ex-sx)+abs(ey-sy)]是(sx,sy)到(ex,ey)的步数,t是前提时间。
AC代码:
#include<stdio.h>
#include<string.h>
char map[10][10];
int xx[4]={1,-1,0,0};
int yy[4]={0,0,1,-1};
bool vis[10][10];
int n,m,t,ans,ex,ey;
int iabs(int a){return a>0?a:-a;}
void dfs(int x,int y,int step)
{
int i,j,dx,dy;
if(ans==1)
return ;
if(step>t)
return ;
if(step==t && map[x][y]=='D')
{
ans=1;
return ;
}
int temp=iabs(x-ex)+iabs(y-ey)+step;
if((t-temp)%2==1)//奇偶性不同
return ;
for(i=0;i<4;i++)
{
dx=x+xx[i];
dy=y+yy[i];
if(dx>=0 && dx<n && dy>=0 && dy<m && map[dx][dy]!='X' && vis[dx][dy]==false)
{
vis[dx][dy]=true;
dfs(dx,dy,step+1);
vis[dx][dy]=false;
}
}
}
int main()
{
int i,j;
int sx,sy;
while(scanf("%d %d %d",&n,&m,&t)!=EOF)
{
if(n==0 && m==0 && t==0)
break;
memset(vis,false,sizeof vis);
for(i=0;i<n;i++)
scanf("%s",map[i]);
int count=0;
for(i=0;i<n;i++)
{
for(j=0;j<m;j++)
{
if(map[i][j]=='S')
{
sx=i;
sy=j;
vis[i][j]=true;
}
if(map[i][j]=='D')
{
ex=i;
ey=j;
}
if(map[i][j]=='.')
count++;
}
}
if(count+1<t)
{
printf("NO\n");
continue;
}
ans=0;
dfs(sx,sy,0);
if(ans==1)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}