1.2 二分
本次主要講到整數(shù)二分和浮點(diǎn)數(shù)二分,整數(shù)二分要考慮到邊界問題,浮點(diǎn)數(shù)二分較為容易回怜,可以采用精度控制法和循環(huán)次數(shù)控制法。
1.2.1 整數(shù)二分
- 二分和單調(diào)性的關(guān)系(有單調(diào)性的 一定可以二分)
- 二分是確定區(qū)間上滿足某個(gè)性質(zhì)的邊界點(diǎn)
- 二分的模板是一定能找到解的
//區(qū)間[l,r]被劃分為[l, mid]和[mid + 1, r]時(shí)使用
int bsearsh_1(int l,int r)
{
while(l < r)
{
int mid= l+r>>1;
if(check(mid)) r = mid;
else l = mid + 1;
}
return l;
}
//區(qū)間[l, r]被劃分為[l, 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;
}
步驟
- 先寫check函數(shù)
- 看下l r 更新方式 如果是 l =mid (板子1 mid補(bǔ)上1) 否則是 r =mid
- 補(bǔ)上加1防止進(jìn)入死循環(huán)
- 習(xí)題 789 數(shù)的范圍
#include<iostream>
using namespace std;
const int N=1e6+10;
int q[N];
int main()
{
int n,m,x;
scanf("%d %d",&n,&m);
for(int i=0;i<n;i++){
scanf("%d",&q[i]);
}
while(m--){
scanf("%d",&x);
int l=0,r=n-1,mid;
while(l<r){
mid=l+r>>1;
if(q[mid]>=x) r=mid;
else l= mid+1;
}
if(q[l]!=x)cout<<"-1 -1\n";
else {
cout<<l<<" ";
int l=0,r=n-1,mid;
while(l<r){
mid=(l+r+1)>>1;
if(q[mid]<=x) l=mid;
else r =mid-1;
}
cout<<l<<endl;
}
}
}
1.2.2 浮點(diǎn)數(shù)二分
- 不用考慮處理邊界問題余佃,較容易。
- 經(jīng)驗(yàn)值:誤差區(qū)間比題目要求多乘
#include<iostream>
using namespace std;
const double t=1e-8;
int main()
{
//cout<<t;
double a,l=-10000,r=10000,mid;
cin>>a;
while((r-l)>t){
mid=(l+r)/2;
if(mid*mid*mid<=a) l=mid;
else r=mid;
}
printf("%.6lf",l);
}