题意:输入一个n*m的迷宫,和一个T:可以在迷宫中生存的最大时间。S为起点,D为终点。并且,每个格子只能踩一次,且只能维持一秒,然后该块地板就会塌陷。所以你必须每秒走一步,且到D点时,所用时间为T。用深搜。
之前,误以为就是找到最短路,结果不是,而是要看是否能在所有可能的路中找到刚好满足条件的路程,后来,单用深搜,超时,所以,后来的剪枝非常重要!!!
#include<iostream>
using namespace std;
int sx,sy,ex,ey;
int n,m;
char map[10][10];
int flag,step;
int d[4][2]={0,1,1,0,0,-1,-1,0};
void dfs(int x,int y,int t)
{
if(flag==1) return ; //若找到所需解,则不用再找其余路径
if(t<abs(ex-x)+abs(ey-y)||(t-abs(ex-x)+abs(ey-y))%2) return ; //剪枝。若剩余时间-当前点到终点的横纵坐标之和,为偶数
//则,该路,可走。(若无障碍,差值为0,若有障碍则绕道
//即差值-1+(n*2+3)为偶数)
else if(t==0) //t代表剩余时间,每走一步t--,这里若t=0,则迷宫坍塌
{
if(x==ex&&y==ey) {flag=1; return ;} //若此时,t=0且刚好到达终点,则标记找到所需解。
else { return ; }
}
else
for(int i=0;i<4;i++) //每次向4个方向探。
{
int nx=x+d[i][0],ny=y+d[i][1];
if (nx>0&&nx<=n&&ny>0&&ny<=m&&(map[nx][ny]=='.'||map[nx][ny]=='D')) //若该点不为墙,则为可走
{
map[nx][ny]='X'; //标记走过
dfs( nx,ny,t-1) ;
map[nx][ny]='.'; //回溯
}
}
return ;
}
int main()
{
char str[10];
int t;
while (scanf("%d%d%d",&n,&m,&t)!=EOF)
{
if(n==0&&m==0&&t==0) return 0;
for (int i=1;i<=n;i++)
{
scanf("%s",str);
for (int j=1;j<=m;j++)
{
map[i][j]=str[j-1];
if(map[i][j]=='S') sx=i,sy=j;
else if(map[i][j]=='D') ex=i,ey=j;
}
}
flag=0;
dfs(sx,sy,t);
if(flag==0) printf("NO\n");
else printf("YES\n");
}
return 0;
}