您的位置:首页 > 其它

HDU 1010 Tempter of the Bone(DFS+奇偶剪枝)

2016-10-28 00:50 477 查看
题意:从S走到D,D只有在t时会开,走过的点不能再访问,问是否能在t时走到D

挺BFS套路的题。。但是为了训练DFS的思想所以用DFS进行求解了~

首先记录S和D的位置(sx,sy)(ex,ey)

从(sx,sy)开始dfs,设初始时刻为0

将访问过的点设为’X’,D在非t时刻都为’O’

从每个点的上下左右方向中有’.’的位置分别dfs,并且在有’O’的位置判断下一时刻是否为t,是则说明能到达

每次访问完一种情况后将访问点再重置为’.’

然后是剪枝:

如果已经可以到达,则不再继续dfs;

然后用奇偶剪枝优化:

某位置(x,y)到(ex,ey)的最小路程长度是(abs(x-ex)+abs(y-ey)),并且如果中间有障碍物绕开时,一定是增加偶数个(可以是0个):









↓ → → →D



↓ →

X ↓

←↓

↓ → → →D

(2个)



↓ →

X ↓

 ↓

 → → →D

(0个)

因此如果当前点能到达D,那么它们的距离(abs(x-ex)+abs(y-ey))+偶数步=剩下来的时间(t-time)

因此如果 (t-time)-(abs(x-ex)+abs(y-ey))为奇数,则一定不能到达,直接return

最后打印结果即可~

#include <iostream>
#include <cstdio>
#include <cmath>
using namespace std;
const int N=10;
int n,m,t,ans=0;
int sx,sy,ex,ey;
char maze

;
int flag=0;
void dfs(int x,int y,int time){

if(flag) return;
int temp=(t-time)-(abs(x-ex)+abs(y-ey));//奇偶剪枝
if(temp<0||temp&1) return;

if(time==t){
maze[ex][ey]='D';
}
else{
maze[ex][ey]='O';
}

maze[x][y]='X';

for(int dy=-1;dy<=1;dy++){
int ny=y+dy;
if(ny>=0&&ny<m){
if(maze[x][ny]=='O'&&time+1==t){
flag=1;
return;
}
else if(maze[x][ny]=='.'){
dfs(x,ny,time+1);
maze[x][ny]='.';
}

}

}
for(int dx=-1;dx<=1;dx++){
int nx=x+dx;
if(nx>=0&&nx<n){
if(maze[nx][y]=='O'&&time+1==t){
flag=1;
return;
}
if(maze[nx][y]=='.'){
dfs(nx,y,time+1);
maze[nx][y]='.';
}
}
}

}
int main(){
while(~scanf("%d %d %d",&n,&m,&t)&&n&&m&&t){
flag=0;
getchar();
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
scanf("%c",&maze[i][j]);
if(maze[i][j]=='S'){
sx=i;sy=j;
}
else if(maze[i][j]=='D'){
ex=i;ey=j;
}
}
getchar();
}
dfs(sx,sy,0);

flag?puts("YES"):puts("NO");
}
}
/*
2 3 3
S.X
..D
*/
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: