题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1010
题意:
有一只小狗需要从N*M迷宫里逃离,出发点标记为'S','X'为不可走,'D'为出口,出口是一扇门,只有在T时刻才打开。问小狗能否逃离迷宫?
T (1 < N, M < 7; 0 < T < 50)
简单带回溯的dfs,很久以前做过,时隔两年,为了复习算法又遇此题。结果还超时了,一脸懵逼,然后果断看以前的代码(我好菜),加了一个奇偶剪枝,AC。
#include
#include
#include
#include
#include
#include
#include
using namespace std;
#define all(x) (x).begin(), (x).end()
#define for0(a, n) for (int (a) = 0; (a) < (n); (a)++)
#define for1(a, n) for (int (a) = 1; (a) <= (n); (a)++)
#define mes(a,x,s) memset(a,x,(s)*sizeof a[0])
#define mem(a,x) memset(a,x,sizeof a)
#define ysk(x) (1<<(x))
typedef long long ll;
//const int INF = ;
const int maxn= 7 ;
int n,m,T,endX,endY;
char a[maxn+2][maxn+2];
bool vis[maxn+2][maxn+2];
int dir[4][2]={ {-1,0},{0,+1},{+1,0},{0,-1} };
bool in(int x,int y)
{
return 0<=x&&x<=n-1&&0<=y&&y<=m-1;
}
bool dfs(int x,int y,int time)
{
if(abs(x-endX)+abs(y-endY)>T-time || (T-time-abs(x-endX)+abs(y-endY))%2 ) return false;
for0(j,4)
{
int tx=x+dir[j][0],ty=y+dir[j][1];
if(!in(tx,ty)||vis[tx][ty]||a[tx][ty]=='X') continue;
if(a[tx][ty]=='D'&&time+1==T) return true;
vis[tx][ty]=1;
if(dfs(tx,ty,time+1)) return true;
vis[tx][ty]=0;
}
return false;
}
int main()
{
int startX,startY;
while(~scanf("%d%d%d",&n,&m,&T)&& n+m+T!=0)
{
for0(i,n) for0(j,m)
{
scanf(" %c",&a[i][j]);
if(a[i][j]=='S')
{
startX=i,startY=j;
}
else if(a[i][j]=='D')
{
endX=i,endY=j;
}
}
mem(vis,0);
vis[startX][startY]=1;
puts(dfs(startX,startY,0)?"YES":"NO");
}
return 0;
}