目录
整数二分模板
//区间[l,r]被划分成[l,mid]和[mid+1,r]时使用
int bsearch_1(int l,int r){
while(l<r){
int mid=(l+r)/2;
if(check(mid)) r=mid; //check()判断mid是否满足某条件
else l=mid+1;
}
return l;
}
//区间[l,r]被划分成[l,mid-1]和[mid,r]时使用
int bsearch_2(int l,int r){
while(l<r){
int mid=(l+r+1)/2; //如果l与r只相差1,如l=3,r=4,如果check满足条件,l=(l+r)/2=3,则会出现死循环
if(check(mid)) l=mid;
else r=mid-1;
}
return l;
}
例题:
数的范围
输入:
第一行两个整数n和m,表示数的长度和询问次数
第二行n个整数(1<=n<=10000),表示这n个数字
接下来m行,每行一个整数x,表示一个询问元素
输出:
共m行,每行两个整数,表示所求元素的起始位置和终止位置
如原数中不存在该元素,则返回“-1 -1“。
#include <bits/stdc++.h>
using namespace std;
int main(){
int n,m;
int q[100010];
scanf("%d%d",&n,&m);
for(int i=0;i<n;i++){
scanf("%d",&q[i]);
}
//while(m--)
for(int i=1;i<=m;i++)
{
int x;
scanf("%d",&x);
int l=0,r=n-1;
while(l<r){
int mid=(l+r)/2;
if(q[mid]>=x) r=mid;
else l=mid+1;
}
if(q[l]!=x) printf("-1 -1");
else{
printf("%d ",l);
int l=0,r=n-1;
while(l<r){
int mid=(l+r+1)/2;
if(q[mid]<=x) l=mid;
else r=mid-1;
}
printf("%d",l);
}
}
return 0;
}
浮点数二分
例题:输入:一个数;输出:该数的平方根;
#include <bits/stdc++.h>
using namespace std;
int main(){
double x;
scanf("%lf",&x);
double l=0,r=x;
//while(r-l>1e-8)
for(int i=1;i<=100;i++)
{
double mid=(l+r)/2;
if (mid*mid>=x) r=mid;
else l=mid;
}
printf("%lf",l);
return 0;
}
如果输出保留四位小数,while(r-l>1e-6)
如果输出保留五位小数,while(r-l>1e-7)
如果输出保留六位小数,while(r-l>1e-8)