题目链接:https://vijos.org/d/ybttg/p/5c24bbe9f41362c9e1912767 时间限制:1000 ms 内存限制:512 MiB
明明做作业的时候遇到了 n n n个二次函数 S i ( x ) = a x 2 + b x + c S_i(x)= ax^2 + bx + c Si(x)=ax2+bx+c,他突发奇想设计了一个新的函数 F ( x ) = max { S i ( x ) } , i = 1 … n F(x) = \max\{S_i(x)\}, i = 1\ldots n F(x)=max{Si(x)},i=1…n。 明明现在想求这个函数在 [ 0 , 1000 ] [0,1000] [0,1000]的最小值,要求精确到小数点后四位,四舍五入。
输入包含 T T T组数据,每组第一行一个整数 n n n;
接下来 n n n行,每行 3 3 3个整数 a a a, b b b, c c c,用来表示每个二次函数的 3 3 3个系数。注意:二次函数有可能退化成一次。
每组数据输出一行,表示新函数 F ( x ) F(x) F(x)的在区间 [ 0 , 1000 ] [0,1000] [0,1000]上的最小值。精确到小数点后四位,四舍五入。
2 1 2 0 0 2 2 0 0 2 -4 2
0.0000 0.5000
对于 50 % 50\% 50%的数据, 1 ≤ n ≤ 100 1 \leq n \leq 100 1≤n≤100;
对于 100 % 100\% 100%的数据, 1 ≤ T ≤ 10 , 1 ≤ n ≤ 1 0 5 , 0 ≤ a ≤ 100 , 0 ≤ ∣ b ∣ ≤ 5000 , 0 ≤ ∣ c ∣ ≤ 5000 1 \leq T \leq 10,1 \leq n \leq 10^5, 0 \leq a \leq 100, 0 \leq |b| \leq 5000, 0 \leq |c| \leq 5000 1≤T≤10,1≤n≤105,0≤a≤100,0≤∣b∣≤5000,0≤∣c∣≤5000。
题意:求这个函数 F ( x ) F(x) F(x)在 [ 0 , 1000 ] [0,1000] [0,1000]的最小值。 思路:利用三分,首先把 l ∼ r l \sim r l∼r这个区间分成三部分( m l ml ml和 m r mr mr)。接下来就是判断,我们因为要求最小值,所以我们要使得左边的值尽可能的小,这样最左边就是最小的。接下来就是找出 m l ml ml和 m r mr mr的 F ( x ) F(x) F(x),如果 m l ml ml的 F ( x ) F(x) F(x)值小于 m r mr mr的 F ( x ) F(x) F(x)值,那么就将 r r r向左边靠近,即 r = m r r = mr r=mr,否则 l = m l l = ml l=ml。
/* * @Author: lzyws739307453 * @Language: C++ */ #include <bits/stdc++.h> using namespace std; const double eps = 1e-9; const int MAXN = 1e5 + 5; struct ios_in { inline char gc() { static char buf[MAXN], *l, *r; return (l == r) && (r = (l = buf) + fread(buf, 1, MAXN, stdin), l == r) ? EOF : *l++; } template <typename _Tp> inline ios_in & operator >> (_Tp &x) { static char ch, sgn; for (sgn = 0, ch = gc(); !isdigit(ch); ch = gc()) { if (!~ch) return *this; sgn |= ch == '-'; } for (x = 0; isdigit(ch); ch = gc()) x = (x << 1) + (x << 3) + (ch ^ '0'); sgn && (x = -x); return *this; } }Cin; int n, t; int a[MAXN], b[MAXN], c[MAXN]; double Check(double x) { double max_ = -1 / eps; for (int i = 1; i <= n; i++) max_ = max(max_, a[i] * x * x + b[i] * x + c[i]); return max_; } int main() { Cin >> t; while (t--) { Cin >> n; for (int i = 1; i <= n; i++) Cin >> a[i] >> b[i] >> c[i]; double l = 0, r = 1000; while (r - l > eps) { double ml = l + (r - l) / 3; double mr = r - (r - l) / 3; if (Check(ml) < Check(mr)) r = mr; else l = ml; } printf("%.4lf\n", Check(l)); } return 0; }