蓝桥杯——青蛙过河(JAVA)

题目:

小青蛙住在一条河边, 它想到河对岸的学校去学习。小青蛙打算经过河里 的石头跳到对岸。

河里的石头排成了一条直线, 小青蛙每次跳跃必须落在一块石头或者岸上。 不过, 每块石头有一个高度, 每次小青蛙从一块石头起跳, 这块石头的高度就 会下降 1 , 当石头的高度下降到 0 时小青蛙不能再跳到这块石头上(某次跳跃 后使石头高度下降到 0 是允许的)。

小青蛙一共需要去学校上 x 天课, 所以它需要往返2x 次。当小青蛙具有 一个跳跃能力 y 时, 它能跳不超过 y 的距离。

请问小青蛙的跳跃能力至少是多少才能用这些石头上完 x 次课。

输入格式

输入的第一行包含两个整数 n,x, 分别表示河的宽度和小青蛙需要去学校 的天数。请注意 2x 才是实际过河的次数。

第二行包含 n−1 个非负整数H1​,H2​,⋯,Hn−1​, 其中Hi​>0 表示在河中与 小青蛙的家相距 i 的地方有一块高度为 Hi​ 的石头, Hi​=0 表示这个位置没有石 头。

输出格式

输出一行, 包含一个整数, 表示小青蛙需要的最低跳跃能力。

样例输入

5 1
1 0 1 0

样例输出

4

样例说明

由于只有两块高度为 1 的石头,所以往返只能各用一块。第 1 块石头和对岸的距离为 4,如果小青蛙的跳跃能力为 3 则无法满足要求。所以小青蛙最少需要 4 的跳跃能力。

评测用例规模与约定

对于30% 的评测用例, n≤100;

对于 60% 的评测用例, n≤1000;

对于所有评测用例, 1≤n≤105,1≤x≤109,1≤Hi​≤104 。

运行限制

  • 最大运行时间:1s
  • 最大运行内存: 512M

代码: 

import java.util.Scanner;

public class Main {
    static int n,x;                  //河的宽度和上学的天数
    public static void main(String[] args) {
        Scanner sc=new Scanner(System.in);
        int sum=0;
        n=sc.nextInt();
        x=sc.nextInt();
        int[] H=new int[n];          //储存石头的位置以及高度
        int[] b=new int[n];          //储存每块石头之前可以跳跃的次数
        for (int i=1;i<n;i++){
            H[i]=sc.nextInt();
            sum+=H[i];
            b[i]=sum;
        }
        int left=1,right=n,middle,S=0;  //二分法查找最小跳跃距离
        while(left<=right){
            middle=left+right>>1;       //>>是位运算符X+Y>>1相当于(X+Y)/2
            if (check(middle,b)){
                S=middle;

                right=middle-1;

            }else {
                left=middle+1;

            }

        }
        System.out.println(S);
        sc.close();
    }

    private static boolean check(int middle, int[] b) {   //查b集合的每个区间是否都有至少2*x个落脚点。
        for (int i=1;i+middle<=n;i++){
            if (b[i+middle-1]-b[i-1]<2*x){
                return false;
            }
        }
        return true;
    }
}

思路:这道题用了二分法的查找方法。

1.我们先进行一个转换,1只小青蛙去x天学校总共需要往返2*x次,转化为2*x只小青蛙过一次河。

2.我们将每块石头及之前石头可以跳跃的次数储存起来,以题目中给的例子为例,b[1]=1,b[2]=1,b[3]=2,b[4]=2。

3.采用二分法找最少跳跃距离,再一次次将midder(跳跃距离)在b集合的区间里找是否所有的区间都可以满足至少有2*x个落脚点(每次青蛙跳离一块石头后,之后的距离区间都要保证有2*x个落脚点,否则就会有青蛙跳不过去,所以要将所有区间都进行比较),如果可以先将midder储存起来(因为可能有更小的跳跃距离),再用二分法逐步比较,直到二分结束输出最终的最小跳跃距离。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值