菜鸡面对大数据范围瑟瑟发抖。。。
我本来看到这道题有多个数据点,然后预处理一个函数就差不多快超时了,还以为不可做呢。。。
看来其实是我太菜了。。。
有个很重要的东西:
这道题中\(0 \leq a \leq 100\)!
说明当这个函数是二次的时候一定是开口向上的!
大概可以发现:我们要求的这个\(F(x)\)是一个下凸的函数,而我们要求的就是这个最小值所在的函数值。
面对这些单峰的函数,我们直接使用三分法就可以求解了。三分法也挺简单的,就不讲了。
为什么上面有粗体字呢?因为这个样例很坑,没有帮你纠正这个错误!
所以最后记得输出函数值而不是相应的x就可以了。
代码:
#include<cstdio>
#include<algorithm>
#define ll long long
const int maxn = 10005;
const double eps = 1e-10;
struct Nodes
{
ll a, b, c;
} s[maxn];
ll n;
double F(double x)
{
double ans = -9999999999;
for(int i = 1; i <= n; i++) ans = std::max(ans, s[i].a * x * x + s[i].b * x + s[i].c);
return ans;
}
void init()
{
}
ll read()
{
ll ans = 0, s = 1;
char ch = getchar();
while(ch > '9' || ch < '0'){ if(ch == '-') s = -1; ch = getchar(); }
while(ch >= '0' && ch <= '9') ans = (ans << 3) + (ans << 1) + ch - '0', ch = getchar();
return s * ans;
}
int main()
{
int T = read();
while(T--)
{
init();
n = read();
for(int i = 1; i <= n; i++) s[i].a = read(), s[i].b = read(), s[i].c = read();
double l = 0, r = 1000;
for(int i = 1; i <= 100; i++)
{
double mid = (l + r) / 2;
if(F(mid - eps) < F(mid + eps)) r = mid + eps;
else l = mid - eps;
}
printf("%.4lf\n", F(l));
}
return 0;
}