题目背景
tz大佬从遥远的喜马拉雅山挖出了一个N阶的函数,为了研究这个神奇的函数,tzdalao把函数拉到了编程俱乐部。
题目描述
这棵函数是N次函数,经过观察发现,在闭区间[l,r]内函数存在一个极大值点,请求出这个极大值点x。
输入输出格式
输入格式:
第一行,一个正整数N和两个实数l、r,表示闭区间范围。
第二行,N+1个实数,从左到右依次表示函数的系数。
输出格式:
输出x的值,四舍五入保留5位小数。
输入输出样例
输入样例#1:
3 -0.9981 0.5
1 -3 -3 1
输出样例#1:
-0.41421
说明
上述样例是n = 3,x3 -3x2 - 3x + 1
思路:
假设求闭区间l到r中的极大值,取l和r的中间值mid,再取左半边l和mid的中间值midmid:如果f(midmid)<f(mid),那么极大值肯定在midmid到r之间,就更新左边界就好了,让l=midmid。如果f(midmid)>f(mid),那么极大值肯定在l到mid之间,就更新右边界就好了,让r=mid。如果f(midmid)==f(mid),更新左右边界,l=midmid,r=mid。
AC代码:
#include<bits/stdc++.h>
using namespace std;
int n;
double l,r;
double I[1000];
double o(double a,int b)//求a的b次方,double
{
double ans=1.00000;
for(int i=0;i<b;i++)
ans *= a;
return ans;
}
double f(double x)//求函数值
{
double ans=0;
for(int i=0;i<=n;i++)
ans += I[i]*o(x,n-i);
return ans;
}
int main()
{
scanf("%d%lf%lf",&n,&l,&r);
for(int i=0;i<=n;i++)
scanf("%lf",&I[i]);
while(r-l>1e-6) //精度
{
double mid=(l+r)/2.0;
double midmid=(l+mid)/2.0;
if(f(midmid)<f(mid))
l=midmid;
else if(f(midmid)>f(mid))
r=mid;
else
{
l=midmid;
r=mid;
}
}
printf("%.5lf",l);
return 0;
}