基础算法--二分

模板:

整数二分:


// 区间[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;
}

浮点数二分:

bool check(double x) {/* ... */} // 检查x是否满足某种性质

double search(double l, double r)
{
    const double eps = 1e-6;   // eps 表示精度,取决于题目对精度的要求
    while (r - l > eps)
    {
        double mid = (l + r) / 2;
        if (check(mid)) r = mid;
        else l = mid;
    }
    return l;
}

例题:P1024 [NOIP2001 提高组] 一元三次方程求解

        (链接:[NOIP2001 提高组] 一元三次方程求解 - 洛谷)

题目描述

有形如:ax3+bx2+cx+d=0ax3+bx2+cx+d=0 这样的一个一元三次方程。给出该方程中各项的系数(a,b,c,da,b,c,d 均为实数),并约定该方程存在三个不同实根(根的范围在 −100−100 至 100100 之间),且根与根之差的绝对值 ≥1≥1。要求由小到大依次在同一行输出这三个实根(根与根之间留有空格),并精确到小数点后 22 位。

提示:记方程 f(x)=0f(x)=0,若存在 22 个数 x1x1​ 和 x2x2​,且 x1

输入格式

一行,44 个实数 a,b,c,da,b,c,d。

输出格式

一行,33 个实根,从小到大输出,并精确到小数点后 22 位。

输入输出样例

输入

1 -5 -4 20

输出

-2.00 2.00 5.00

代码:

#include
#include
#include
using namespace std;
double a,b,c,d;
double x1,x2;
double x;
double num;
bool check(double mid,double num){
	if(num > 0){
		if(a*mid*mid*mid+b*mid*mid+c*mid+d > 0)
			return true;
		else return false;
	}
	else if(num < 0){
		if(a*mid*mid*mid+b*mid*mid+c*mid+d < 0)
			return true;
		else return false;
	}
}
int main(){
	cin >> a >> b >> c >> d;
	x1 = (-b + sqrt(b * b - 3 * a * c)) / (3 * a);
	x2 = (-b - sqrt(b * b - 3 * a * c)) / (3 * a);
	//最左边
	double l = -100.0,r = min(x1,x2);
	num = a*r*r*r + b*r*r + c*r + d;
	while(r - l > 1e-7){
		double mid = ( l + r ) / 2;
		if(check(mid,num)) r = mid;
		else l = mid;
	}
	printf("%.2f ",l);
	//中间
	l = min(x1,x2),r = max(x1,x2);
	num = a*r*r*r + b*r*r + c*r + d;	
	while(r - l > 1e-7){
		double mid = (l + r) / 2;
		if(check(mid,num)) r = mid;
		else l = mid;
	}
	printf("%.2f ",l);
	//最右边
	l = max(x1,x2), r = 100;
	num = a*r*r*r + b*r*r + c*r + d;	
	while(r - l > 1e-7){
		double mid = (l + r) / 2;
		if(check(mid,num)) r = mid;
		else l = mid;
	}
	printf("%.2f",l);
	return 0;
}
/*
  1 -5 -4 20
 */

你可能感兴趣的:(算法,java,数据结构,c++)