likes
comments
collection
share

奇怪的电梯广搜做法~

作者站长头像
站长
· 阅读数 6

一、题目描述:

一种很奇怪的电梯,大楼的每一层楼都可以停电梯,而且第 i 层楼(1 ≤ i ≤ N)上有一个数字 Ki (0 ≤ Ki ≤ N)。电梯只有四个按钮:开,关,上,下。上下的层数等于当前楼层上的那个数字。当然,如果不能满足要求,相应的按钮就会失灵。例如: 3, 3, 1, 2, 5 代表了 Ki(K1=3, K2=3,……),从 1 楼开始。在 1 楼,按“上”可以到 4 楼,按“下”是不起作用的,因为没有 -2 楼。那么,从 A 楼到 B 楼至少要按几次按钮呢?

来源:洛谷 www.luogu.com.cn/problem/P11…

输入格式

共二行。 第一行为三个用空格隔开的正整数,表示 N, A, B(1≤N≤200,1≤A,B≤N )。 第二行为 N 个用空格隔开的非负整数,表示 Ki

5 1 5
3 3 1 2 5

输出格式

一行,即最少按键次数,若无法到达,则输出 -1

3

二、思路分析:

首先看一下输入数据是什么意思,首先输入一个N, A, B,也就是分别输入楼层数(N)、开始楼层(A)、 终点楼层(B)。 在例子中,我们的 楼层数N是5,也就是说有5层楼,第二行就是这5层楼的每层楼的数字k。

1、题目中说到只有四个按钮:开,关,上,下,上下的层数等于当前楼层上的那个数字,众所周知,电梯的楼层到了的时候啊,它是会自动打开的,没有人进来的时候,也会自动关上,这里求的是最少按几个按钮,所以我们在这里不用看开关,也就是可以看作该楼层只有两个按钮 +k 、 -k

2、题目中提到最少按几次,很明显,这是一个搜索题。当出现最少的时候,我们就可以考虑用广搜了(也可以用深搜做的啦)

3、这里注意一下,就是我们在不同的按钮次数时遇到停在同一楼层,这时候就会出现一个重复的且没有必要的搜索,所以我们需要在搜索的时候加个条件。

三、AC 代码:


import java.util.*;

public class Main {
	public static void main(String[] args) {
		Scanner sr = new Scanner (System.in);
		int N = sr.nextInt();              
		int A = sr.nextInt();             
		int B = sr.nextInt();              
		
		// 广搜必备队列
		Queue<Fset> Q = new LinkedList<Fset>();
		// 一个记忆判断,看看这层楼是不是来过
		boolean[] visit = new boolean[N+1];
		// 来存楼梯按钮的,假设第3层的k是2,  那么 k[3][0]=2 (向上的按钮)、 k[3][1]=-2 (向下的按钮)
		int[][] k = new int [N+1][2];
		for(int i = 1 ; i <= N ; i++){
			k[i][0] = sr.nextInt();
			k[i][1] = -k[i][0];
		}	
		
		// 存一个起始楼层和按钮次数到队列
		Q.add(new Fset(A,0));
		// 当队列为空也就是所以能走的路线都走过了,没有找到就可以返回-1了
		while(!Q.isEmpty()){ 
			Fset t = Q.poll();
			// 找到终点楼层,不用找了直接输出并退出搜索
			if(t.floor == B){ 
				System.out.println(t.count);
				return;
			}
			// 
			for(int j = 0 ; j < 2 ; j++){
				// 按键后到的楼层
				int f = t.floor + k[t.floor][j];
				// 判断按键后到的楼层是否有效和是否走过
				if(f >= 1 && f <= N && visit[f]!=true) {
					Q.add(new Fset(f,t.count+1));
					// 做标记
					visit[f]=true;
				}  
        	}
        }
        // 没找到
        System.out.println(-1);
	}
}

class Fset{
	int floor; // 当前楼层
	int count; // 当前按键次数
	public Fset(int floor, int count) {
		this.floor = floor;	
		this.count = count;
	}
}

奇怪的电梯广搜做法~

四、总结:

为什么用的队列呢? 因为队列的排队取出的,首先判断的一定是按钮次数最少的,感觉这道题用广搜或者深搜效果其实差不多,我写的深搜多一个判断,就是当当前次数超过我找到的最少按钮次数,我就丢弃这个。 广搜像晕染吧,往四周分散搜索,

嗯,就酱~

转载自:https://juejin.cn/post/7073817170618089479
评论
请登录