浮点数的二分答案

286 阅读1分钟

冒险了一整天的可莉和 LCZ 饿坏了,所以他们想到河边炸鱼。为大冒险做足功课的 LCZ 突然想到最近这里是雨季,水位随时会涨起来,他还发现这里的河岸的形状可以看作如下方程f(x) = 2x^5 + 3x^4 + 3x^3 + 3x^2 + 3^x (0<=x<=100)

LCZ 为了保证安全,他想知道当水位达到 k 的时候河岸会有多宽的部分会被水淹没,你快来帮帮他吧

input

输入包含多组数据,每组数据占一行,每行一个整数 k(0≤k≤20303030300)​,含义如题。

output

对于每个输入数据 k,输出一个实数,代表河岸被淹部分的宽度,保留小数点后 3 位(四舍五入),每个输出占一行。


这是校赛的一道题 错误的原因是因为 没有做过二分类型的应用题 给我k 让我求x 我并没有想到是用二分查找的方式 ,我一开始想的是如何变幻公式 这不是计算机思维 是错误的 后面我想到了求出k的整数部分再枚举小数 但是正确的解法应该是使用浮点数的二分查找逼近答案

先给出二分查找的模板

{
    double n; 
    cin>>n;
    double l=-10000,r = 10000;//答案所在区间
    while(r-l >= 1e-8)//误差范围比要求输出的小数范围再多两个小数点
    {
        double mid = (l+r) / 2;
        if(check(mid) < n )    r = mid;//与题目要求的数字作比较 该情况证明mid相比最终答案还小了
        else  l = mid;
    } 
    printf("%.xlf",l);
return 0;
}

题目的代码

#include <iostream>
#include <cmath>

using namespace std;
long long  x(double n)
{
	long long ans = 2*pow(n,5) + 3*( pow(n,4) + pow(n,3) + pow(n,2) + n);
	return ans ;
}
int main()
{
	double n;
	long long k;
	while (cin >> k)
	{	
		double l = 0.0,r = 100.0;
		while ( r-l >= 1e-5 )
		{
			double mid = (l+r)/2;
			if( x(mid) < k)	 l = mid;
			else r = mid ;
		}
		printf("%.3lf\n",l);
	}
return 0;
}