题目:HDU 1010 Tempter of the Bone
题目大意:给定N, M, T, 问是否可以从S开始刚好走T步到达D(门).
题解: 很显然DFS搜索一条满足条件的路,不过要注意的是搜索过程中的剪枝,不然就TLE 这题涉及到的剪枝为奇偶剪枝
#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<map>
#include<stack>
#include<queue>
#include<ctime>
#include<cstring>
#include<string>
#define LL __int64
#define INF 0x3f3f3f3f3f
using namespace std;
char c[10][10];
int n, m, k, sx, sy, ex,ey;
int dx[4]={0,1,0,-1};
int dy[4]={1,0,-1,0};
bool flag=false;//用于判断是否YES
void dfs(int x, int y, int step)
{
int i;
if(x==ex&&y==ey&&step==k) flag=true;
if(flag) return;
//奇偶剪枝
int ans=k-step-abs(x-ex)-abs(y-ey);
if(ans<0 || ans&1) return;
for(i=0; i<4; i++)
{
int Dx=x+dx[i];
int Dy=y+dy[i];
if(Dx<1 || Dx>n || Dy<1 || Dy>m)continue;//超界
if(c[Dx][Dy]!='X')
{
c[Dx][Dy]='X';//当前标记为已走过
dfs(Dx, Dy, step+1);
c[Dx][Dy]='.';//走另外一条路时候应该恢复当前这个点的原有状态 , 回溯
}
}
return ;
}
int main()
{
int i, j;
while(~scanf("%d%d%d", &n, &m, &k))
{
getchar();//吞掉回车 , 不然会一直WA -_-!
if(!n&&!m&&!k) break;
flag=false;
int space=0;//记录可走格子总数 ('.' and 'D')
for(i=1; i<=n; i++)
{
for(j=1; j<=m; j++)
{
scanf("%c", &c[i][j]);
if(c[i][j]=='S') sx=i, sy=j;
if(c[i][j]=='D') ex=i, ey=j, space++;
if(c[i][j]=='.') space++;
}
getchar();//吞掉回车
}
if(space<k) printf("NO\n");//可走格子总数小于规定的步数
else
{
c[sx][sy]='X';
dfs(sx, sy, 0);
if(flag) printf("YES\n");
else printf("NO\n");
}
}
return 0;
}