P1883 【模板】三分 / 函数
题目描述
给定 \(n\) 个二次函数 \(f_1(x),f_2(x),\dots,f_n(x)\)(均形如 \(ax^2+bx+c\)),设 \(F(x)=\max\{f_1(x),f_2(x),...,f_n(x)\}\),求 \(F(x)\) 在区间 \([0,1000]\) 上的最小值。
输入格式
输入第一行为正整数 \(T\),表示有 \(T\) 组数据。
每组数据第一行一个正整数 \(n\),接着 \(n\) 行,每行 \(3\) 个整数 \(a,b,c\),用来表示每个二次函数的 \(3\) 个系数,注意二次函数有可能退化成一次。
输出格式
每组数据输出一行,表示 \(F(x)\) 的在区间 \([0,1000]\) 上的最小值。答案精确到小数点后四位,四舍五入。
输入输出样例 #1
输入 #1
2
1
2 0 0
2
2 0 0
2 -4 2
输出 #1
0.0000
0.5000
说明/提示
对于 \(50\%\) 的数据,\(n\le 100\)。
对于 \(100\%\) 的数据,\(T<10\),\(\ n\le 10^4\),\(0\le a\le 100\),\(|b| \le 5\times 10^3\),\(|c| \le 5\times 10^3\)。
题解
#include <bits/stdc++.h>
using namespace std;
const int N=1e5+10;
const double eps = 1e-9;
typedef long long ll;
int n;
struct Node
{
double a,b,c;
}fx[N];
double f(double x)
{
double res=fx[1].a*x*x+fx[1].b*x+fx[1].c;
for(int i=2;i<=n;i++)
{
res = max(res,fx[i].a*x*x+fx[i].b*x+fx[i].c);
}
return res;
}
void solve()
{
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>fx[i].a>>fx[i].b>>fx[i].c;
}
double l=0.0,r=1000.0;
while(r-l>eps)
{
double mid1 = (2*l+r)/3;
double mid2 = (2*r+l)/3;
double res1 = f(mid1);
double res2 = f(mid2);
if(res1<res2) r = mid2;
else l = mid1;
}
double ans = f(l);
printf("%.4lf\n",ans);
}
int main()
{
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int t=1;
cin>>t;
while(t--)
{
solve();
}
return 0;
}

浙公网安备 33010602011771号