题目大意:一条狗因为某种原因陷入迷宫,需要在规定第T秒走到终点才能走出迷宫;给出一个迷宫判断狗能否走出迷宫。
hdu1010
思路:要在第T秒到达指定地点 用DFS;第一次很容易的写出了代码,但是卡在了剪枝;进行两次剪枝操作;1:n*m-X的数量<=t(这个很容易理解为什么自己想)2:判断剩下步数和最短路径的关系,如果剩下步数小于最短路径就剪枝,如果剩下步数是奇数证明当前位置无法按时到达终点,剪枝,因为到达一个位置要绕点路的话消耗的步数一定是偶数。第二步剪枝具体操作见代码,有注解。
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
int n,m,t,b[11][11],step,sx,sy,ex,ey,f;
char c[8][8];
int dx[4]={0,0,-1,1},dy[4]={1,-1,0,0};
void dfs(int x,int y)
{
int temp=t-step-(abs(x-ex)+abs(y-ey));//记录剩下步数减去最短路径长度
//如果小于0则当前位置无法按时到达终点
//如果是奇数则也无法到达终点。因为多余的步数 多绕一点路消耗是偶数
//奇数能到达终点旁边一个无法跨入终点
//cout<<"x="<<x<<" y="<<y<<" step="<<step<<endl;
int x1,y1;
b[x][y]=1;
if(x==ex&&y==ey&&step==t){f=1;return;}
if(temp<0||temp&1)return;
if(f==1||step>t){return;}
for(int i=0;i<4;i++)
{
x1=x+dx[i];
y1=y+dy[i];
if(x1>=0&&x1<n&&y1>=0&&y1<m&&b[x1][y1]==0&&(c[x1][y1]=='.'||c[x1][y1]=='D')&&t>step)
{
step++;
dfs(x1,y1);
step--;
b[x1][y1]=0;
}
}
}
int main()
{
while(cin>>n>>m>>t)
{
int sux=0;;
getchar();
if(n==0&&m==0&&t==0)break;
memset(b,0,sizeof(b));
for(int i=0;i<n;i++)
{
scanf("%s",c[i]);
}
for(int i=0;i<n;i++)
{
for(int j=0;j<m;j++)
{
if(c[i][j]=='S'){sx=i;sy=j;}
if(c[i][j]=='D'){ex=i;ey=j;}
if(c[i][j]=='X')sux++;
}
}
if(n*m-sux<=t){
cout<<"NO"<<endl;
continue;
}
step=0;
f=0;
dfs(sx,sy);
if(f)cout<<"YES"<<endl;
else cout<<"NO"<<endl;
}
return 0;
}