分巧克力------二刷获新知
作者:
cyuyu
,
2022-04-06 17:41:15
,
所有人可见
,
阅读 177
代码
#include<iostream>
using namespace std;
const int N=1e5+10;
int n,k;
struct res{
int l,w;
}a[N];
bool check(int mid){
int sum=0;
for(int i=0;i<n;i++){
sum+=(a[i].l/mid)*(a[i].w/mid);
if(sum>=k)
return true;
}
return false;
}
int main(){
cin>>n>>k;
int i=0;
int temp=2e8;
int t=n;
while(t--){
int l,w;
cin>>l>>w;
a[i].l=l;
a[i].w=w;
i++;
temp=min(temp,l);
temp=min(temp,w);
}
int l=1;
int r=N;
while(l<r){
int mid=(l+r+1)/2;
if(check(mid))
l=mid;
else
r=mid-1;
}
cout<<r<<endl;
return 0;
}
新知:
- 巧克力可以拼凑:比如一个巧克力是22,还有其他的巧克力,最后巧克力的边长可能大于2,这块 22的巧克力不参与分的过程,所以不能以最小的长/宽的值作为二分的右端点,直接将r=1e5就可以了,因为合适的长度一定在[1,1e5]这个区间内!
- 为什么二分使用这个模板呢?
这里我们二分的是巧克力的最大边长,那么只需要让这个边长分得的巧克力的数量大于小朋友的数量就可以了。
所以应该取右端点,即l=mid
->mid=(l+r+1)/2