地址:
点击打开链接
如我所想,跨过了BFS,就是DFS,然而上来的这个题和我想得不大一样,还难了一些。
用的是递归的方法。而且里面还有许多小trick
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#include<queue>
#define inf 0x3f3f3f3f
#define MAX 10
#define repf(i,from ,to) for(int i =from ; i <to ; i++)
using namespace std;
char Map[MAX][MAX];
int visit[MAX][MAX];
int d[4][2]={{-1,0},{1,0},{0,1},{0,-1}};
int n,m,t,ex,ey,flag;
//迭代深搜
void dfs(int sx,int sy,int step)
{
int i,dx,dy;
if(sx==ex&&sy==ey&&step==t)
{
flag =1 ;
return ;
}
int item = t-step-abs(ex-sx)-abs(ey-sy);
//进行剪枝操作
if(item<0||item&1)
return ;
for(i = 0 ; i <4 ; i ++)
{
dx = sx+d[i][0];
dy = sy+d[i][1];
//越界的情况 ,直接跳
if(dx<0||dy>=m||dy<0||dx>=n)
continue ;
if(Map[dx][dy]!='X'&&visit[dx][dy]==0)
{
visit[dx][dy]=1;
dfs(dx,dy,step+1);
visit[dx][dy]=0;
}
}
return ;
}
int main(){
int i , j , wall ;
int sx,sy;
while(cin>>n>>m>>t)
{
if(n==0&&m==0&&t==0)
break;
flag = 0 ;
//对wall进行计数的目的是为了实现后面的一个小trick
wall = 0 ;
memset(visit,0,sizeof(visit));
for(i = 0 ; i < n ; i++)
{
for(j = 0 ;j<m;j++)
{
cin>>Map[i][j];
if(Map[i][j]=='S')
{
sx=i;sy=j;
}
if(Map[i][j]=='D')
{
ex = i,ey=j;
}
if(Map[i][j]=='X')
{
wall++;
}
}
}
//trick one ,这个可以举个例来看一下,就知道对错了,因为t是必须准时进行。
if(t+wall+1>m*n)
{
cout <<"NO"<<endl;
continue ;
}
//出发点可以直接设置为已经搜索
visit[sx][sy]=1;
//迭代深搜
dfs(sx,sy,0);
if(flag==1)
{
cout << "YES"<<endl;
}
else {
cout << "NO" <<endl;
}
}
return 0 ;
}