title: 二分算法
date: 2019-05-23 18:27:52
tags: 二分
二分算法
有单调性一定可以二分,但是可以二分的题 不一定就具有单调性 只需要能够分成两半 一半满足,另一半不满足
整数二分边界问题是关键啊
看mid属于左边还是右边,即 更新是l=mid 还是r=mid 从而选取模板
1、当我们将区间 [l, r] 划分成 [l, mid] 和 [mid + 1, r] 时,
其更新操作是 r = mid或者 l = mid + 1 ;
计算mid时不需要加1
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;
}
2、当我们将区间 [l, r] 划分成 [l, mid - 1] 和 [mid, r] 时,
其更新操作是 l = mid或者 r = mid - 1;
此时为了防止死循环,计算mid时需要加1
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;
}
3.浮点数二分
就不存在边界问题 不存在+1 -1问题 直接就是l=mid 或者r=mid
//开三次方根要注意复数的情况
#include <iostream>
#include <algorithm>
const int maxn=1e4+5;
using namespace std;
int main()
{
double n;
cin>>n;
int flag=0;
if(n<0)
{
flag=1;
n=-n;
}
double l=0,r=n;
while(r-l>1e-7)//这个地方也可以写成直接把区间二分100次
//for(int i=0;i<100;i++) 相当于把原区间长度/2^100
{
double mid=(r+l)/2.0;
//cout<<"mid "<<mid<<endl;
if(mid*mid*mid>=n)
r=mid;
else
l=mid;
/*这样也可以
double mid=(r+l)/2.0;
//cout<<"mid "<<mid<<endl;
if(mid*mid*mid<=n)
l=mid;
else
r=mid;
*/
}
if(!flag)
printf("%lf\n",l);
else
printf("-%lf\n",l);
return 0;
}