/*此题是经典的dfs,博主最近在看dfs将此题列出作为一个类型,思想就是图的暴力搜索以及记忆以及经典的奇偶剪枝*/
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
int n, m, t, dx, dy, sx, sy, flag;
char maze[10][10];
int direction[4][2]={{0,1},{1,0},{0,-1},{-1,0}};//四个方向任意规定目的四个方向都要有
int visit[10][10];
void dfs(int a, int b, int s){
visit[a][b] = 1;//将走过的点置为1表示访问过
if(flag == 1) return ;//这里是一个标志变量结束的一个小剪枝
if(a == dx && b == dy){//这里是主要停止走的原因当此时通过递归得到的点是终点的的坐标且走的步数恰好为题目要求的步数时结束
if(s == t)
flag = 1;
return ;
}
if(s >= t){
flag = 0;
return ;
}
for(int i = 0; i < 4; i++){
int x = a + direction[i][0];
int y = b + direction[i][1];
if(x >= 0 && x < n && y >= 0 && y < m && maze[x][y] != 'X' && !visit[x][y]){
dfs(x, y, s+1);
visit[x][y] = 0;
if(flag) return;//这里注意剪枝不然超时
}
//else break;这里不用单独判断四个方向扫描完后会自动跳出并回溯到上个岔路口的节点
}
}
int main(){
while(scanf("%d%d%d",&n,&m,&t)!=EOF &&( n|| m|| t)){
getchar();//这里读掉输入完的数字后的回车
memset(visit, 0, sizeof(visit));
for(int i=0; i<n; i++){
for(int j=0; j<m; j++){
scanf("%c", &maze[i][j]);
if(maze[i][j]=='S'){
sx=i;
sy=j;
}else if(maze[i][j]=='D'){
dx=i;
dy=j;
}
}
getchar();//以为是字符的读入所以需要注意最后的换行符读掉
}
if(abs(sx-dx)+abs(sy-dy)>t||(sx+dx+sy+dy+t)%2==1) //剪枝
{
printf("NO\n");
continue;
}
flag=0;
dfs(sx,sy,0);
if(flag==1){
printf("YES\n");
}
else if(flag == 0){
printf("NO\n");
}
}
return 0;
}
/*总结搜索题总之得思路清楚判断清楚边界不能总是依赖模板这样才能走得更远虽然博主自己提交时提交了很多次在不断完善的过程就是进步 切忌暴躁 平静下来,博主此时正是大二,每周学长们组织好多场比赛,虽然也会有时因为进步慢而急躁但进步的过程是不能少的,也许他人可以在比赛的时候搜题解而多于我的题量但是我多他们的是思考题是做不完的只有日积月累的小技巧和经验,这些才是我们立足走远的凭证,切忌急躁慢下来,慢不是停滞不前不是无所追求而是积淀,我相信随之而来的是爆发,博主会继续用心写每一篇题解希望能够帮助你理解也祝愿所有看到的都能有所触动。*/
hdu1010
最新推荐文章于 2025-08-07 10:45:56 发布