练习题:
P8647 [蓝桥杯 2017 省 AB] 分巧克力
P8647 [蓝桥杯 2017 省 AB] 分巧克力 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
二分法找到可以满足分给每人一块的最大值。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int a[100010][2],N,K,t=0,ans;
int main()
{
cin>>N>>K;
int i,ans;
for(i=0;i<N;i++)
{
cin>>a[i][0]>>a[i][1];
t=max(t,min(a[i][0],a[i][1]));//找一条大的边当右边界就行,第二个函数用max也行,好像不是很讲究
}
int l,r,mid;
l=1,r=t;
while(l<=r)
{
mid=(l+r)/2;
int f=0;
for(i=0;i<N;i++)
f+=(a[i][0]/mid)*(a[i][1]/mid);//计算边长为mid时可以分多少快
if(f>=K){//找可以分的最大值
ans=mid;
l=mid+1;
}
else r=mid-1;
}
cout<<ans<<endl;
}
P1678 烦恼的高考志愿
P1678 烦恼的高考志愿 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
目的找到一个与估计分数最接近的学校然后累加差值,一个一个找时间的需要太久,所以要用到二分法找到一个刚刚大于估计分数的学校,当然使用二分法之前需要先排序。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;//记得答案用long long
ll a[100010],b[100010];
ll n,m,i,ans=0;
int fen(int f);
int main()
{
cin>>m>>n;
for(i=0;i<m;i++)cin>>a[i];
for(i=0;i<n;i++)cin>>b[i];
sort(a,a+m);
for(i=0;i<n;i++)
{
ans+=fen(b[i]);//累加差值
}
cout<<ans;
}
int fen(int f)
{
if(f<=a[0])return a[0]-f;//这种情况需要特判
ll l,r,mid;
l=0,r=m-1;
while(l<r)//找到第一个大于估计分数的学校
{
mid=(l+r)/2;
if(a[mid]<f){
l=mid+1;
}
else {
r=mid;
}
}
return min(abs(a[l]-f),abs(f-a[l-1]));//前面一个小的可能更接近,所以返回一个和估计分数更接近的差值
}
P1296 奶牛的耳语
P1296 奶牛的耳语 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)
只需要排序后找到最后一个可以交流到的奶牛
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
ll n,d,a[1000010],i,j,ans;
int main()
{
cin>>n>>d;
for(i=0;i<n;i++)
cin>>a[i];
sort(a,a+n);//排序
for(i=0;i<n;i++){
ll l=i,r=n-1,mid,t;//t用来记录最后那一只的序号
while(l<=r){//一直寻找到极限距离
mid=(l+r)/2;
if(a[mid]<=a[i]+d)
{
l=mid+1;
t=mid;
}
else r=mid-1;
}
ans+=t-i;
}
cout<<ans;
}