题目链接:点击打开链接
题目大意:给你许多个一元二次函数的三个系数a, b, c 的值,函数 f ( x ) ,在【1, 1000】的定义域上,f ( x ) = max(s1 ( x ), s2 ( x)......) , s ( x )指的是不同的a, b, c, 对应的那个 一元二次函数, 求出 f ( x )的最大值
AC Code:
//#include<bits/stdc++.h>
//一个注意的问题: 三分之后得出的左右边界有可能不等,所以要大体估算循环的次数,因为如
//果按照二分那种左右边界相等的情况可能会出现无限循环的情况
#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn = 10010;
int a[maxn], b[maxn], c[maxn];
int n;
double f(double x)
{
double xx = (double)a[0]*x*x + (double)b[0]*x + (double)c[0]; //因为有可能全部都为负值
for(int i = 1; i < n; i++)
{
double A = (double)a[i];
double B = (double)b[i];
double C = (double)c[i];
xx = max(A*x*x + B*x + C, xx);
}
return xx;
}
//double Search(double left, double right)
//{
// //(double)left; //这样子好像不管用
// //(double)right;
// for(int i = 1; i <= 100; i++)
// {
// double p = left + (right-left)/3; //这个三分是怎么推出来的??
// double q = right - (right-left)/3;
// if(f(p) > f(q)) //要根据实际的函数来!!
// left = p;
// else
// right = q;
// }
// cout << left << " "<< right << endl;
// return left;
//}
double Search(double left, double right)
{
for(int i = 0; i < 100; i++)
{
double mid = (left+right)/2;
double mmid = (mid + right)/2;
if(f(mid) < f(mmid)) // 注意左右界限的变化要根据实际的函数图像的走向变化来判断和确定
right = mmid;
else
left = mid;
}
return left;
}
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
scanf("%d", &n);
for(int i = 0; i < n; i++)
scanf("%d %d %d", &a[i], &b[i], &c[i]);
double x = Search(0, 1000);
printf("%.4lf\n", f(x));
}
return 0;
}