二分答案(模板)
注意:l<=r时 r=mid-1; //补充:l<=r,r最后会经历等于l,所以r最好等于上界 【l同理】,也可不等,当r>上界时,令其pan值为无穷大,即可大于上界
l<r时 r=mid; //补充:l<r,r永不等于l,所以r一定要大于上界【l同理】
不然会出错,以后用第二种写法
新模板(根据hetion):
ll l=0,r=1e14+7; //这里要注意上界和下界,l应该<=最小值
while(l<r){ //注意这里没有=
ll mid=(l+r)>>1;
if(pan(mid,a)) r=mid; //这里不能r=mid-1
else l=mid+1;
}
ll ans=l-1; //l和l-1视情况而定
题目:分巧克力(AcWing)
枚举也是暴力的一种
当枚举规模较大时可以用二分
所以此题用二分答案(即用二分枚举答案)
#include<bits/stdc++.h>
using namespace std;
namespace{
template<typename T>
inline void read(T &s){
T f=1;s=0;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-1;
for(;isdigit(ch);ch=getchar()) s=(s<<1)+(s<<3)+(ch^48);
s*=f;
}
}
#define fio ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);
int n,k;
int h[100005];
int w[100005];
int main(){
read(n);read(k);
for(int i=1;i<=n;++i){
read(h[i]);read(w[i]);
}
int l=1;
int r=100002;
int ans=0;
while(l<=r){ //不管是l<=r还是l<r,最后答案都是l-1
int mid=(l+r)>>1;
int cnt=0;
//以下为判断答案是否满足条件
for(int i=1;i<=n;++i){
cnt+=(h[i]/mid)*(w[i]/mid); //**每块能分 (h/mid) * (w/mid)**
}
if(cnt>=k){
l=mid+1;
ans=mid;
}
else r=mid-1;
}
cout << ans; //ans==l-1
return 0;
}