分巧克力(二分查找)

cpp 复制代码
#include <iostream>
using namespace std;
int main()
{
  // 请在此输入您的代码
  int n,k;
  cin>>n>>k;
  int N=100005;
  int a[N],b[N];
  for(int i=0;i<n;i++){
    cin>>a[i]>>b[i];
  }
  int l=1,r=1e5;
  int ans;
  while(l<=r){
    int mid=l+(r-l)/2;
    long long cnt=0;
    for(int i=0;i<n;i++){
      cnt+=a[i]/mid*(b[i]/mid);
    }
    if(cnt>=k){
      ans=mid;
      l=mid+1;
    } else{
      r=mid-1;
    }
  }
  cout<<ans;
  return 0;
}

二分查找的核心在于找到**单调性,**具体来说:

  • 如果某个边长 mid 可以切割出至少 K 块巧克力 ,那么 任何比 mid 小的边长都能切割出更多(或者至少同样多)块巧克力。
  • 如果某个边长 mid 无法切割出至少 K 块巧克力 ,那么 任何比 mid 大的边长也无法满足条件。

这意味着我们可以使用 二分查找 来找到最大可行的边长。

cnt :计算当前 mid 下每块巧克力可以切割出的块数

注意cnt+=a[i]/mid*(b[i]/mid); 如果写成cnt += a[i] * b[i] / mid;先乘法会溢出导致结果出错,所以要先分别除以mid再乘。

判断条件

如果 cnt >= k,说明当前 mid 可以切割出足够多的巧克力块。此时,可以尝试增大 mid,因此调整 l = mid + 1,并将 ans = mid 记录下来。

如果 cnt < k,说明 mid 太大,无法切割出足够的块数,因此将 r = mid - 1,减少 mid 的值

相关推荐
梁辰兴1 小时前
数据结构:排序
数据结构·算法·排序算法·c·插入排序·排序·交换排序
Murphy_lx1 小时前
Lambda表达式
开发语言·c++
yangpipi-1 小时前
C++并发编程-23. 线程间切分任务的方法
开发语言·c++
野犬寒鸦1 小时前
力扣hot100:搜索二维矩阵 II(常见误区与高效解法详解)(240)
java·数据结构·算法·leetcode·面试
菜鸟得菜1 小时前
leecode kadane算法 解决数组中子数组的最大和,以及环形数组连续子数组的最大和问题
数据结构·算法·leetcode
楼田莉子2 小时前
C++算法专题学习——分治
数据结构·c++·学习·算法·leetcode·排序算法
一支鱼2 小时前
leetcode常用解题方案总结
前端·算法·leetcode
ulias2123 小时前
各种背包问题简述
数据结构·c++·算法·动态规划
m0_570466413 小时前
代码随想录算法训练营第二十八天 | 买卖股票的最佳实际、跳跃游戏、K次取反后最大化的数组和
java·开发语言·算法
程序喵大人3 小时前
分享个C++线程池的实现源码
开发语言·c++·线程池