题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1010
#include <iostream>
#include <cmath>
#include <string.h>
using namespace std;
/****************************************************************************************************************
题意:
找到图中规定起点和终点以及步数的路径,YES or NO
思路:
1,用了一下 BFS,结果懵逼了,因为没法做到规定步数。
2,因此用 DFS,核心在于(利用回溯可以找到每条路径,判断路径长度即可)
3,第一次见可以用回溯的~太方便的说。时间还可以优化,而我太渣了。。。
****************************************************************************************************************/
char map[10][10];
int visit[10][10];
int flag,n,m,T;
int id[4][2]={0,-1,0,1,1,0,-1,0};
int in_x,in_y,out_x,out_y;
void dfs(int x,int y,int t)
{
if(flag || visit[x][y]) return ; //访问剪枝和找到结果剪枝
if(x>n || y>m || x<=0 || y<=0) return ; //边界剪枝
if(t == T && x == out_x && y == out_y) {flag=1; return ;} //找到结果
int temp = (T-t) - abs(x-out_x) - abs(y-out_y);
if( temp < 0 || temp&1 ) return; //奇偶剪枝
visit[x][y]=1;
for(int i = 0;i < 4;i ++){
int tx=x+id[i][0],ty=y+id[i][1];
if(map[tx][ty] != 'X' && !visit[tx][ty]){
dfs(tx,ty,t+1);
visit[tx][ty]=0; //回溯,不懂为什么要回溯!!!
}
}
}
int main()
{
while(cin>>n>>m>>T)
{
memset(visit,0,sizeof(visit));
memset(map,'X',sizeof(map));
if(n == 0 && m == 0 && T == 0) break;
int wall=0;
for(int i = 1;i <= n;i ++){
for(int j = 1;j <= m;j ++){
cin>>map[i][j];
if(map[i][j] == 'S') {in_x=i;in_y=j;}
else if(map[i][j] == 'D') {out_x=i;out_y=j;}
else if(map[i][j] == 'X') wall++;
}
}
if(n*m - wall <= T){ //我擦勒~~~这里简直是神优化! time: 468-78.这就是差距
cout<<"NO"<<endl; //也许是出题人给的数据的原因吧,如果空路的个数小于要求的步数,肯定到不了
continue;
}
flag=0;
dfs(in_x,in_y,0);
if(!flag)
cout<<"NO"<<endl;
else
cout<<"YES"<<endl;
}
return 0;
}