黑科技蓝桥杯冬令营算法训练——二分查找

导读

二分查找是一个比较重要且实用的基础算法

题目链接:用户登录

读完题目的大体想法:

  题目大致意思就是有几块巧克力分给k个人然后要求在每个人得到巧克力尽可能大的情况下求最大的正方形边长。

  第一感觉,如果时间允许,暴力枚举是一定可以出答案的,但是这个题目的数据100000,可能会超时,所以我们就可以自然而然的想到运用二分查找来节约时间去寻找那个最大的边长,这样其实就差不多有感觉了。

处理一下细节:

1.如何得出在当前边长下,能分出几块巧克力:

分出的块数(ans)=(巧克力长度/当前边长)*(巧克力宽度/当前边长);

2.然后ans和人数K比一下,ans>=k说明边长有点小,可以再大一点;ans<k说明边长太大不够分了;

如果处理了以上两个问题其实题目已经出来了,结合二分查找的模板,很容易就写出来了

//find函数就是来判断切出来的巧克力有没有超过有的人数k; 
public static boolean find(int mid,int k,int n){
        int ans=0;//记录有多少块
        for (int i=0;i<n;i++) {
            ans += (h[i] / mid) * (w[i] / mid);//遍历累加切出来有多少块巧克力
            if (ans >= k) return true;
            //这边在循环里直接判断有没有大于k可以稍微节约一点时间,
            // 算是小小的优化,写在for循环外面当然也可以;
            // 只要当前已经大于k了之后的就不用加了直接返回true
        }
         return false;
    }

 public static void main(String[] args) {
        int i1=1;//注意二分查找的开头,边长从1开始
        int j1=100000;//最大的边长
        //常规输入
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int k=sc.nextInt();
        for (int i=0;i<n;i++){
            h[i]=sc.nextInt();
            w[i]=sc.nextInt();
        }
        while (i1<=j1){ //二分模板就是套!
            int mid=(i1+j1)/2;
            if (find(mid,k,n)){
                i1=mid+1;
            }
            else {
                j1=mid-1;
            }
        }
        System.out.println(j1);
    }

在此贴心的附上AC代码:

import java.util.Scanner;

public class Main {
    static int [] h=new int [100000];
    static int [] w=new int [100000];
    public static boolean find(int mid,int k,int n){
        int ans=0;
        for (int i=0;i<n;i++) {
            ans += (h[i] / mid) * (w[i] / mid);
            if (ans >= k) return true;
        }
         return false;
    }
    public static void main(String[] args) {
        int i1=1;
        int j1=100000;
        Scanner sc=new Scanner(System.in);
        int n=sc.nextInt();
        int k=sc.nextInt();
        for (int i=0;i<n;i++){
            h[i]=sc.nextInt();
            w[i]=sc.nextInt();
        }
        while (i1<=j1){
            int mid=(i1+j1)/2;
            if (find(mid,k,n)){
                i1=mid+1;
            }
            else {
                j1=mid-1;
            }
        }
        System.out.println(j1);
    }
}
  • 8
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值