#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
的值