您的位置:首页 > 其它

hdu 1010 Tempter of the Bone(dfs+枝剪)

2017-12-19 15:25 393 查看
题目:http://acm.hdu.edu.cn/showproblem.php?pid=1010

题意:n*m的地图,规定恰好在第t步到达终点'D',起点是‘S’,墙是‘X’

思路:还是走迷宫的题,每次上下左右走,暴力所有情况,找到恰好是t步的路径,每次回溯再回到初始状态。

    但还有一个奇偶枝剪,意思就是要求的最短路径是|ex-sx|+|ey-sy|,若要到达终点,必须多走偶数步。

    什么奇偶枝剪,在main里判断一下即可。

#include<bits/stdc++.h>
using namespace std;
int n,m,t,sx,sy,ex,ey,xnum;
bool visit[10][10],flg;
char mp[10][10];
const int dir[4][2] = {{1,0},{0,1},{-1,0},{0,-1}};

void dfs(int x, int y, int step) {
if(flg) return; //一种情况即可
if(step == t && x == ex && y == ey) {
flg=true;
return;
}
if(step >= t) return; //搜索的路径大于t时返回
//int dis = abs((double)x-ex) + abs((double)y-ey);
//dis = t-dis-step;
//if(dis<0 || dis%2) return;//奇偶剪枝
for( int i=0; i<4; ++i) {
int tx = x+dir[i][0];
int ty = y+dir[i][1];
int tstep = step+1;
if(tx>=0 &&tx<n &&ty>=0 &&ty<m &&!visit[tx][ty] &&mp[tx][ty] != 'X') {
visit[tx][ty] = true;
dfs(tx,ty,tstep);
visit[tx][ty] = false;//回溯
}
}
return;
}

int main(){
while(scanf("%d%d%d",&n,&m,&t)&&(n+m+t)){
xnum=0;
flg=0;
for(int i=0;i<n;i++)
for(int j=0;j<m;j++){
cin>>mp[i][j];
visit[i][j]=false;
if(mp[i][j]=='S'){
visit[i][j]=true;
sx=i;
sy=j;
}
if(mp[i][j]=='D'){
ex=i;ey=j;
}
if(mp[i][j]=='X')
++xnum;
}
int dis = abs((double)sx-ex) + abs((double)sy-ey);
if(t%2==0&&dis%2==1|| t%2==1&&dis%2==0){
cout<<"NO"<<endl;
continue;
}
if(n*m-xnum>t) //这点也很着重要,如果可走的步数比赛t还小直接pass
dfs(sx,sy,0);
if(flg)
cout<<"YES"<<endl;
else
cout<<"NO"<<endl;
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: