hdu 1010 Tempter of the Bone(dfs+剪枝)

题目链接:hdu 1010 Tempter of the Bone(dfs+剪枝)

题意:狗狗从S出发,要在正好t秒的时候到达D,每一块地只能走一次,X代表墙不能走,问能否到达

思路:深搜,但是需要剪枝,每走一步,判断能否在剩下的时间中不考虑墙通过最短的路到达出口,若不能直接返回。

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<iostream>
using namespace std;
typedef long long ll;

char s[10][10];
int vis[10][10];
int nxt[4][2]={0,1,0,-1,1,0,-1,0};
int sx,sy,ex,ey;
int n,m,t;
int flag;

bool judge(int i,int j){
	if(i<0||i>=n||j<0||j>=m||(s[i][j]=='X')||vis[i][j])return 0;
	return 1;
}

void dfs(int x,int y,int time){
	if((x==ex)&&(y==ey)){
		if(time==t)flag=1;
		return ;
	}
	if(time>=t)return ;
	if((t-time)<(abs(x-ex)+abs(y-ey)))return ;
	int nx,ny;
	for(int i=0;i<4;i++){
		nx=x+nxt[i][0];
		ny=y+nxt[i][1];
		if(!judge(nx,ny))continue;
		vis[nx][ny]=1;
		dfs(nx,ny,time+1);
		vis[nx][ny]=0;//不成功要记得还原vis
		if(flag)return ;
		
	}
}

int main(){
	while(~scanf("%d%d%d",&n,&m,&t)){
		if(!n&&!m&&!t)break;
		for(int i=0;i<n;i++){
			scanf("%s",s[i]);
		}
		for(int i=0;i<n;i++){
			for(int j=0;j<m;j++){
				if(s[i][j]=='S'){
					sx=i;sy=j;
				}
				if(s[i][j]=='D'){
					ex=i;ey=j;
				}
			}
		}
		memset(vis,0,sizeof(vis));
		flag=0;
		vis[sx][sy]=1;
		dfs(sx,sy,0);
		if(flag)printf("YES\n");
		else printf("NO\n");
	}
	return 0;
}

猜你喜欢

转载自blog.csdn.net/yz467796454/article/details/81390867