hdoj1728 java 深搜

本文探讨了一种深搜算法,加入了拐弯数限制条件,用于判断能否在给定的最大拐弯数内从起点到达终点。通过优化访问标记方式,避免了不必要的搜索,提高了效率。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


题目意思很明确就是给你起点和终点,还有一个最大拐弯数,判断能否在最大拐弯数之内从起点走到终点,

本题在思考的时候比正常的深搜的题目增加了一个思考点,就是拐弯数,怎么能把拐弯数加进程序,怎么能判断本次走的方向和之前的不一样,然后把本次拐弯数增加一,这是这个题的精髓之处。本题有一个本方法,就是创建四个拐弯数,然后一一列出每个深搜,虽然只有四个但是这样写也会显得程序非常臃肿。

我在程序里是这么考虑的,我既然创建了一个四个长度的数组,来控制他的前进方向,那么也就是说我的方向就已经定义好了,那么下一次的方向和本次要走的方向不同就可以用本次的方向数和下次的方向数比较就可以了。

本题还有一个与之前不同的地方,若果拿着按刚才的思路敲出的程序来提交你会悲剧的发现超时了,所以需要剪枝了,于是我们想在什么地方可以剪枝。这就是接下来需要思考的地方了,这次我们要异于常规,以前我们都是定义一个vis数组,用来标记是否访问过此节点,但这次我们可以把他的功能稍作调整,让他初始化时很大,意思就是初始状态的时候它的拐弯数是无穷大,没次访问之后就把当前的拐弯数与之前的比较,如果当前的小就更新此拐弯数,这样如果发现这次的拐弯数比以前的大那么我们直接放弃他就好了

import java.util.Scanner;


public class dfs_main {


static String maps;
//创建地图
static char[][] map = new char[101][101];
//创建地图访问标志
static int[][] vis = new int[101][101];
static int k, x1, y1, x2, y2;
static int n,m;
//标志是否符合条件
static int falg = 0;
static int[] a = {0,1,-1,0};
static int[] b = {1,0,0,-1};
public static void dfs(int w,int x,int y,int dir){
//把初始定义成无穷大,如果本次访问到此节点的拐弯数比上次的大,那么肯定不符合条件
if(w > vis[y][x])
return ;
else {
//如果小的话就更新它的拐弯数
vis[y][x] = w;
}
if(w > k || falg == 1){
return;
}

if(x == x2 && y == y2 && w <= k){
falg = 1;
return ;
}
int l,f,ww = 0;
for(int i=0;i<4;i++){
l = x + a[i];
f = y + b[i];

//如果方向不一致
if( dir != -1 && dir != i ){
ww = w+1;
}
else{
ww = w;
}
if(l>=0 && l<n && f>=0 && f<m && map[f][l]=='.'){

dfs(ww,l,f,i);
}

}
public static void main(String [] args){
Scanner cin = new Scanner (System.in);

int t = cin.nextInt();
while(t!= 0){
t--;
m = cin.nextInt();
n = cin.nextInt();
for(int i=0;i<=m;i++){//数组初始化-*

for(int j=0;j<=n;j++){

vis[i][j]=Integer.MAX_VALUE;
}

for(int i=0;i<m;i++){
maps = cin.next();
map[i] = maps.toCharArray();
}

k = cin.nextInt();
x1 = cin.nextInt()-1;
y1 = cin.nextInt()-1;
x2 = cin.nextInt()-1;
y2 = cin.nextInt()-1;
// System.out.println(k + " " + x1 + " " + x2 + " " + y1 + " " +y2 + " ");
falg = 0;
dfs(0,x1,y1,-1);
if(falg == 1){
System.out.println("yes");
}else{
System.out.println("no");
}
}
}
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值