最近做了些二分题目,做一个小专题。
总结:二分查找有点就是能快速找个一个点介于最小最大中的值,后判断是否达成条件,避免了暴力穷举造成TLE
#include<stdio.h>
#include<stdlib.h>
typedef long long ll;
ll s,mid,l,r,max=-1,tree[1000005];
int main()
{
ll n,m;
scanf("%lld%lld",&n,&m);
for(int i=1;i<=n;i++)
{
scanf("%lld",&tree[i]);
if(max<tree[i])
max=tree[i];//找到最长树
}
r=max;
while(l<=r)
{
mid=(l+r)/2;//二份基值点位伐木机高度
s=0;
for(int i=1;i<=n;i++)
{
if(tree[i]>mid)
s+=tree[i]-mid;//算出是否等于m
}
if(s<m)
r=mid-1;//减小高度使得木材够
else
l=mid+1;
}
printf("%lld",r);
system("pause");
return 0;
}
#include<stdio.h>
#include<stdlib.h>
int a[100005];
int main(){
int n,k;
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
int l=0,r=100000001;
while(l<r){//其实可以l+1的还可以省去后面的特判,做完题目才发现
int cnt=0;
int mid=(l+r)/2;
for(int i=1;i<=n;i++)
{
if(mid!=0)
cnt+=a[i]/mid;
}
if(cnt>=k)
l=mid+1;
else r=mid;
}
if(l!=0)
printf("%d",l-1);
else
printf("0");
system("pause");
return 0;
}
#include<bits/stdc++.h>
using namespace std;
int c[500010];
int n,m,a,j,all,b,t;
bool check(int x){
all=0;
for(int i=1;i<=n;i++)
{
j=c[i]-a*x;//只用太阳晒
if(j<=0)continue;
t=j/b;
if(j%b!=0)t++;//不为整还需加一
all+=t;
if(all>x) return false;
}
return true;
}
int main(){
scanf("%d%d%d",&n,&a,&b);
for(int i=1;i<=n;i++){
scanf("%d",&c[i]);
}
int l=0,r=500010;
while(l<r)
{
int mid=(l+r)/2;
if(check(mid)) r=mid;
else l=mid+1;
}
printf("%d",l);
return 0;
}