HDU-1010-Tempter of the Bone
http://acm.hdu.edu.cn/showproblem.php?pid=1010
给这题折腾了半天啊,刚开始用BFS写的,总是WA,后来发现这题要求在给定的时间点到达,不能早,也不能迟,而BFS每次求出的是最短时间,不合题意,于是转用DFS,剪枝的方法是参考HDU的PPT写的,居然还要考虑奇偶性
可以把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 必然是偶数步
所以:当遇到从 0 走向 0 但是要求时间是奇数的,或者从1 走向 0 但是要求时间是偶数的 都可以直接判断不可达
附一个测试数据
4 4 9
S..X
X.X.
..XD
....
YES
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<math.h>
char map[10][10];
int n,m,t;
int xx,yy;
int flag;
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
int go(int x,int y)
{
if(0<=x&&x<n&&0<=y&&y<m)
return 1;
return 0;
}
void dfs(int x,int y,int cnt)
{
int i,min;
if(cnt==t&&x==xx&&y==yy)
flag=1;
if(flag)
return;
min=abs(x-xx)+abs(y-yy);
if(min>t-cnt) //到目的地的最短时间比所剩时间大
return;
if(cnt>t)
return;
if(min%2!=(t-cnt)%2) //奇偶性不同
return;
for(i=0;i<4;i++)
{
if(go(x+dir[i][0],y+dir[i][1])&&map[x+dir[i][0]][y+dir[i][1]]!='X')
{
map[x+dir[i][0]][y+dir[i][1]]='X';
dfs(x+dir[i][0],y+dir[i][1],cnt+1);
map[x+dir[i][0]][y+dir[i][1]]='.';
}
}
return;
}
int main()
{
int i,j,wall;
int x,y;
while(scanf("%d%d%d",&n,&m,&t),n||m||t)
{
for(i=0;i<n;i++)
scanf("%s",map[i]);
wall=0;
for(i=0;i<n;i++)
for(j=0;j<m;j++)
{
if(map[i][j]=='S')
{
x=i;
y=j;
}
else if(map[i][j]=='D')
{
xx=i;
yy=j;
}
else if(map[i][j]=='X')
wall++;
}
if(n*m-wall<=t) //可走的路小于时间
{
printf("NO\n");
continue;
}
map[x][y]='X';
flag=0;
dfs(x,y,0);
if(flag==1)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}