/*
参考http://www.cnblogs.com/ACMan/archive/2012/05/21/2512295.html
dfs
*/
#include<iostream>
#include<string>
#include<cstring>
#include<cmath>
using namespace std;
char ch[10][10];
int ok = 0, cnt[5][2] = {{0, 1}, {0, -1}, {-1, 0}, {1, 0}};
int n, m, t, sx, sy, ex, ey;//sx, sy,开始点的横纵坐标,ex,ey结束点的横纵坐标
void dfs(int x, int y, int tt)
{
if(tt == t) //剪枝2,到D点时走过的时间刚好停止,直接返回,不需要再搜索了
{
if(x == ex && y == ey)
ok = 1;
return ;
}
int i, xx, yy;
if(ok) return;//满足要求的直接停止搜索;
int temp;
temp = abs(ex-x) + abs(ey-y) - abs(t-tt);//剪枝3,当到达D点的步数大于时间数时,返回
//temp&1 等于 temp%2 ,当出现奇数次的也不可能到达D点,好好理解
if(temp > 0 || temp&1) return ;
for( i=0; i < 4; i++ )
{
xx = x + cnt[i][0];
yy = y + cnt[i][1];
if(xx >= 0 && xx < n && yy >= 0 && yy < m && ch[xx][yy] != 'X')
{
ch[xx][yy] = 'X';
dfs(xx, yy, tt+1);
ch[xx][yy] = '.';//回溯
}
}
}
int main()
{
int wall;
while(scanf("%d%d%d", &n, &m, &t) != EOF && (n || m || t))
{
int i, j;
wall = 0;
for( i=0; i < n; i++ )
{
scanf("%s",ch[i]);
for( j=0; ch[i][j] != '\0'; j++ )
{
if(ch[i][j] == 'S')
sx = i, sy = j;
if(ch[i][j] == 'D')
ex = i, ey = j;
if(ch[i][j] == 'X')
wall++;
}
}
ok = 0;
if(n*m - wall <= t)//剪枝1,当非 X 的个数小于时间数时,直接输出NO
printf("NO\n");
else
{
ch[sx][sy] = 'X';
dfs(sx, sy, 0);
if(ok)
printf("YES\n");
else
printf("NO\n");
}
}
return 0;
}
hdu 1010 Tempter of the Bone
最新推荐文章于 2021-05-23 15:11:46 发布