二分模板
整数二分:
bool check(int x)//检查x是否满足某种性质
{
}
//区间[l,r]被划分为[l,mid]和[mid+1,r]时使用
int bsearch_1(int l,int r)
{
while(l<r)
{
int mid=l+r>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
return l;
}
//区间[l,r]被划分为[,mid-1]和[mid,r]时使用
int bsearch_2(int l, int r)
{
while(l<r)
{
int mid=l+r+1>>1;
if(check(mid)) l=mid;
else r=mid-1;
}
return l;
}
浮点数二分
bool check(double x)
{
}
double bsearch_3(double l,double r)
{
const double eps=1e-6;//一般要比题目所给精度高2
//或者直接循环100次
//for(int i=0;i<100;i++)
while(r-l>eps)
{
double mid=l+r>>1;
if(check(mid)) r=mid;
else l=mid;
}
return l;
}
整数二分例题
/*给定一个按照升序排列的长度为n的整数数组,以及 q 个查询。
对于每个查询,返回一个元素k的起始位置和终止位置(位置从0开始计数)。
如果数组中不存在该元素,则返回“-1 -1”。*/
#include<iostream>
#include<cstdio>
using namespace std;
int a[100005];
int main()
{
int n,q;
scanf("%d%d",&n,&q);
for(int i=0;i<n;i++)
{
scanf("%d",&a[i]);
}
while(q--)
{
int k;
scanf("%d",&k);
int l=0,r=n-1;
while(l<r)
{
int mid=l+r>>1;
if(a[mid]>=k) r=mid;
else l=mid+1;
}
if(a[l]!=k) printf("-1 -1\n");
else
{
printf("%d ",l);
int l=0;r=n-1;
while(l<r)
{
int mid=l+r+1>>1;
if(a[mid]<=k) l=mid;
else r=mid-1;
}
printf("%d\n",r);
}
}
return 0;
}
浮点数二分例题
/*
给定一个浮点数n,求它的三次方根。
输入格式
共一行,包含一个浮点数n。
输出格式
共一行,包含一个浮点数,表示问题的解。
注意,结果保留6位小数。
数据范围
−10000≤n≤10000
*/
#include<iostream>
using namespace std;
int main()
{
double n;
cin>>n;
double l=-10000,r=10000;
while(r-l>1e-8)
{
double mid=(l+r)/2;
if(mid*mid*mid>=n) r=mid;
else l=mid;
}
printf("%.6f",l);
return 0;
}
对于每组输入数据:
第一排 分别是 河的宽度、石头的个数n、最多的跳跃次数.
以下n排是n个石头的坐标,
然后要求在最多跳跃次数以内,每次落地只能在石头上,跳到河的对岸.输出青蛙至少有每次跳多远的能力?
#include<iostream>
#include<algorithm>
using namespace std;
const int N=5e5+10;
int a[N];
int l,n,m;
bool check(int x)//检查x是否满足某种性质 ,x为跳远能力,要检查当前的能力是否能够过河
{
int t;
t=m;
int i=0;
int now=0;//记录当前位置
while(t--)//每一次跳跃
{
while(a[i]-now<=x&&i<=n)//x可以跨过每一个石头,数了数,x能跨过几个石头,这个不一定就能跨过一个
i++;
now=a[i-1];//跳一回到这个石头上
}
//次数用完了,可以走到头,也就是到了最后重点的那个认为的石头,就是答案
if(now==l)//走到头
return true;
else
return false;
}
//区间[l,r]被划分为[l,mid]和[mid+1,r]时使用
int bsearch_1(int l,int r)
{
int mid;
while(l<r)
{
mid=l+r>>1;
if(check(mid)) r=mid;
else l=mid+1;
}
return l;
}
int main()
{
ios::sync_with_stdio(false);//没加这个就超时了
while(cin>>l>>n>>m)
{
for(int i=0;i<n;i++)
{
cin>>a[i];
}
sort(a,a+n);
a[n]=l;
int Max=a[0];
for(int i=0;i<n;i++)
{
Max=max(a[i+1]-a[i],Max);//找出两个相邻石头的最大值
}
cout<<bsearch_1(Max,l)<<endl;
}
return 0;
}