您的位置:首页 > 其它

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

2014-08-13 21:28 393 查看
题意:给一幅图,有起点有墙有终点,问能不能在刚好t秒的时间走到终点

DFS + 多重剪枝(奇偶性剪枝)

一开始果断DFS,交上去TLE了。。。用了好几重的剪枝才过。。。。

所以不要小看剪枝,往往优化个成百上千倍。

一.奇偶剪枝

例如 4*4的矩阵

1 0 1 0

0 1 0 1

1 0 10

0 1 0 1

由1到1 由0到0必走偶数步

由1到0 由0到1必走偶数步

所以 根据这个和时间来判断是否成立

例如

4 4 5

S . X .

. . X .

. . X .

D . . .

代码:

int dis=abs(bx-ex)+abs(by-ey);

if((dis+t)%2!=0){printf("NO\n");continue;} //奇偶剪枝

S处于1的位置 D处于0的位置 则必须经历奇数的步骤才可以到达

如果给的时间是3,5,7,都可以 到达,如果给的时间是4,6一定不行

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
char s[10][10];
int vis[10][10],d[4][2]={0,1,0,-1,1,0,-1,0};
int n,m,ok,t,ex,ey;
void DFS(int a,int b,int con)
{
if(s[a][b]=='D'&&con==t){////在给定的时间时找到出口,查找成功后返回
ok=1;
return ;
}
if(con>=t||ok) return ;//超出时间未找到 放弃
int dis=abs(a-ex)+abs(b-ey);//查找的位置 与终点的距离
if((dis+t-con)%2||(dis>t-con)) return ;// 运动中奇偶 剪枝
vis[a][b]=1;                     //或者剩余的时间到不了既定位置
int x,y,i;
for(i=0;i<4;i++){
x=a+d[i][0];
y=b+d[i][1];
if(x>=0&&y>=0&&x<n&&y<m&&s[x][y]!='X'&&!vis[x][y]){
//前四个 位置剪枝 第五个 不走障碍路 第六个 不走返回路
DFS(x,y,con+1);
}
}
vis[a][b]=0;////将经过 回溯为 未经过
}
int main()
{
int i,j,a,b,ans;
while(scanf("%d%d%d",&n,&m,&t)&&(n!=0&&m!=0&&t!=0)){
memset(vis,0,sizeof(vis));
for(ans=1,i=0;i<n;i++){
scanf("%s",s[i]);
for(j=0;j<m;j++){
if(s[i][j]=='S') {//找到入口位置
a=i,b=j;
s[i][j]='X';
}
if(s[i][j]=='.'){//记录可行路的步数,出口也算,所以从1开始加
ans++;
}
if(s[i][j]=='D'){//z找到出口位置
ex=i,ey=j;
}
}
}
int dis=abs(a-ex)+abs(b-ey);
if(ans<t||(dis+t)%2) {//可行路的个数小于时间 不行,奇偶剪枝
printf("NO\n");
continue;
}
ok=0;
DFS(a,b,0);
//printf("%d\n",ans);
if(ok==1) printf("YES\n");//正确结果
else printf("NO\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: