基础算法 二分
二分模板
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; // 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 >> 1;
if (check(mid)) l = mid;
else r = mid - 1;
}
return l;
}
唯一的区别就在于int mid = l + r + 1 >> 1;
假设 l =r-1,若mid = l+r>>1
因为是下取整,所以此时mid = 2l+1>>1
, mid = l
若此时则行号check(mid)
判断为真,则 执行语句l = l
,陷入死循环中。
习题:
790.数的三次方根
给定一个浮点数n,求它的三次方根。
输入格式
共一行,包含一个浮点数n。
输出格式
共一行,包含一个浮点数,表示问题的解。
注意,结果保留6位小数。
数据范围
−10000≤n≤10000−10000≤n≤10000
输入样例:
1000.00
输出样例:
10.000000
#include<iostream>
#include <cmath>
using namespace std;
double x;
int main(){
cin >> x;
int op = 1;
if(x!=abs(x)){
op = -1;
x = abs(x);
}
double l =0, r = x;
while(abs(l*l*l-x)>=1e-8){
double mid = (l+r)/2;
if(mid*mid*mid>=x) r=mid;
else l = mid;
}
printf("%lf",op*r);
}