您的位置:首页 > 其它

Tempter of the Bone

2013-10-13 11:49 288 查看
hdu1010:http://acm.hdu.edu.cn/showproblem.php?pid=1010

题意: 输入一个n*m的迷宫,和一个T:可以在迷宫中生存的最大时间。S为起点,D为终点。并且,每个格子只能踩一次,且只能维持一秒,然后该块地板就会塌陷。所以你必须每秒走一步,且到D点时,所用时间为T。用深搜。

解题思路: 用深收,但是直接用深收会超时的,必须加上剪枝这里要用奇偶剪枝的方式,减少收索次数。

#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
using namespace std;
char map[8][8]; //记录原来的地图
bool visit[8][8];//标记该点是否被访问
int n,m,t;
int dx,dy,sx,sy;
bool flag;//标记是否找到目标
void dfs(int i,int j,int l)
{
if(flag) return ;//找到目标就返回 ,不用再往下找了
if(l>t) return ; //如果已经超出了时间就不用在找
if(i<1||i>n||j<1||j>m) return ; //如果已经超出了界限街不用再找
if(map[i][j]=='D'&&l==t) {flag=true; return ; }//找到目的地,就标记已经找到
int temp=abs(i-dx)+abs(j-dy);
temp=t-temp-l;   //如果到目的地的距离减去最短距离是奇数,就不用再找,因为这个是一定是偶数
if(temp&1) return ;//奇偶剪枝
if(!visit[i-1][j]&&map[i-1][j]!='X'){ //不是X就是D或者.
visit[i-1][j]=true;//标记当前的点已经找了
dfs(i-1,j,l+1);
visit[i-1][j]=false;//注意这里的改回来,否则下一次收索就会在已经改变的地图上收索了(自己犯过的错误)
}
if(!visit[i+1][j]&&map[i+1][j]!='X'){
visit[i+1][j]=true;
dfs(i+1,j,l+1);
visit[i+1][j]=false;
}
if(!visit[i][j+1]&&map[i][j+1]!='X'){
visit[i][j+1]=true;
dfs(i,j+1,l+1);
visit[i][j+1]=false;
}
if(!visit[i][j-1]&&map[i][j-1]!='X'){
visit[i][j-1]=true;
dfs(i,j-1,l+1);
visit[i][j-1]=false;
}
}
int main(){
int k; //统计x的个数,
while(~scanf("%d%d%d",&n,&m,&t)){
k=0;
memset(visit,false,sizeof(visit));//初始化一定要在这里,之前在下面初始化,结果错了
if(n==0||m==0||t==0)break;
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
cin>>map[i][j];
if(map[i][j]=='S'){
sx=i;
sy=j; //记录出发点的位子
visit[i][j]=true;//出发点一定是被标记的,开始时候忘了这里
}
if(map[i][j]=='D'){
dx=i;
dy=j; //记录目的地的位子
}
if(map[i][j]=='X')
k++;
}
}
flag=false; //注意这里的初始化
if(n*m-k-1>=t)dfs(sx,sy,0); //如果剩余的.个数比t少,显然不能到达D,所以没必要dfs

if(flag)
printf("YES\n");
else
printf("NO\n");
}
}


View Code
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: