这种好搜索题就应该立马再敲一遍!
首先 地图用bool 数组足以 只要表示能走还是不能走
然后以字符串形式输入 或者开头结尾加 getchar();
标记起点和终点的位置。
把起点位置标为1 意思是不可走 然后开始dfs 不用返回值
标记一个全局bool变量 一旦发现 置为1 剩下全return
第一个剪枝 就是 空的地方比可用的时间都烧 直接挂
第二个剪枝 就是 用的时间超过了T 直接挂掉
第三个 最重要的 就是当前还有的时间,也就是还要走的步数 减去 x和y方向的位移量 必须大于零并且是偶数
然后 四个方向 还是用一个dir数组
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cstdlib>
using namespace std;
const int maxn=7;
bool map[maxn][maxn];
int dir[4][2]={{-1,0},{1,0},{0,-1},{0,1}};
bool fin;
int n,m,T;
int doorx,doory;
void dfs(int x,int y,int t)
{
if(x==doorx && y==doory && t==T)
{
fin=1;
return ;
}
if(fin)
return ;
if(t>=T)//剪纸二 如果用时已经超过了T 当然不用再搜索了。
return ;
//开始剪枝三!最重要的剪枝!!!!第一个是要实时判断 剩下的时间是否够省的下的路 差必须>=0
//第二点就是 这个差必须是偶数,这样想,其实从起点到终点,不管怎么走 都是在x y两个方向上移动那么多部
//那么多出来的这么步 必须是对称的 也就是比如x多移动了一步 必须再动回来~!
int tmp=T-t-abs(x-doorx)-abs(y-doory);
if(tmp<0 || tmp&1 )
return ;
for(int i=0;i<4;++i)
{
int newx=x+dir[i][0];
int newy=y+dir[i][1];
if(newx>=0 && newx<n && newy>=0 && newy<m && map[newx][newy]==0)
{
map[newx][newy]=1;
dfs(newx,newy,t+1);
if(fin)
return ;
map[x+dir[i][0]][y+dir[i][1]]=0;//回溯 搜索失败 恢复原来数据
}
}
}
int main()
{
int i,j,wallnum;
int xpos,ypos;
char ch[10];
while(scanf("%d %d %d",&n,&m,&T))
{
if(!n && !m && !T) break;
memset(map,0,sizeof(map));
wallnum=0;
fin=0;
for(i=0;i<n;++i)
{
scanf("%s",ch);
for(j=0;j<m;++j)
{
if(ch[j]=='S')
{
xpos=i;
ypos=j;
map[i][j]=0;
}
else if(ch[j]=='D')
{
doorx=i;
doory=j;
map[i][j]=0;
}
else if(ch[j]=='X')
map[i][j]=1,wallnum++;
else
map[i][j]=0;
}
}
if(n*m-wallnum<T)//第一个剪纸,如果能走的格子连t时间都不够,那不用dfs了
{
printf("NO\n");
continue;
}
map[xpos][ypos]=1;
dfs(xpos,ypos,0);
if(fin)
printf("YES\n");
else
printf("NO\n");
}
return 0;
}