洛谷P1135 Java

题目出处点这里
在这里插入图片描述

思路:很明显可以使用dfs和bfs,这里我选择dfs,当然还有一点小技巧,比如当到达B楼时接收的按钮次数ans都是目前为止的最小值;比如还没到达B楼时,但此时的按钮次数sum已经大于等于之前已经走到B楼的走法的ans,就可以断定这不是最佳走法,直接return即可。相反,如果不加这些判断条件,很可能会TLE甚至栈溢出!

代码里得解释还是很详细的:

package search;

import java.util.Scanner;

public class P1135 {

	static int N, A, B, ans = 999999999;//ans记录最佳最少按按钮得次数,初始值设大点,方便后面比较
	static int[] arr;
	static boolean[] vis;

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		N = sc.nextInt();
		A = sc.nextInt();
		B = sc.nextInt();
		arr = new int[N + 1];
		vis = new boolean[N + 1];
		for (int i = 1; i <= N; i++) {
			arr[i] = sc.nextInt();
		}
		dfs(A, B, 0);
		if (ans != 999999999) {
			System.out.println(ans);
		}else {
			System.out.println(-1);
		}

	}

	// 深搜
	/**
	 * vis存在的意义:因为从A到B有不同的走法,且同一种走法中不能经过相同的楼层,如果经过相同的楼层就说明是另一种走法,因此选择vis记录下一个要走的位置上一次有没有走过
	 * @param start 从哪开始
	 * @param end   到哪开始
	 * @param sum   走到第start楼时已经按了的按钮的次数
	 */
	public static void dfs(int start, int end, int sum) {
		if (start == end) {//如果到达了B楼,就记录目前为止最小的按按钮次数为ans,并return
			ans = Math.min(sum, ans);
			return;
		}
		if (sum >= ans) {//如果还没有到达B楼,但是此时按按钮的次数sum已经大于等于ans,就说明此种走法不是最佳走法,return即可
			return;
		}
		vis[start] = true;// 置为走过
		if (start + arr[start] <= N && !vis[start + arr[start]]) {// 向上走,如果可以的话
			dfs(start + arr[start], end, sum + 1);
		}
		if (start - arr[start] >= 1 && !vis[start - arr[start]]) {// 向下走,如果可以的话
			dfs(start - arr[start], end, sum + 1);
		}
		//当该种走法完成后(可能行得通,也可能行不通),我们应该把该位置重新置为没访问过,供下一种走法使用
		vis[start] = false;
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值