題目鏈接:https://vijos.org/d/ybttg/p/5c24bbe9f41362c9e1912767
時間限制:1000 ms 內存限制:512 MiB
題目描述
明明做作業的時候遇到了個二次函數,他突發奇想設計了一個新的函數。
明明現在想求這個函數在的最小值,要求精確到小數點後四位,四捨五入。
輸入格式
輸入包含組數據,每組第一行一個整數;
接下來行,每行個整數,,,用來表示每個二次函數的個係數。注意:二次函數有可能退化成一次。
輸出格式
每組數據輸出一行,表示新函數的在區間上的最小值。精確到小數點後四位,四捨五入。
樣例數據
樣例輸入
2
1
2 0 0
2
2 0 0
2 -4 2
樣例輸出
0.0000
0.5000
限制與提示
對於的數據,;
對於的數據,。
題解
題意:求這個函數在的最小值。
思路:利用三分,首先把這個區間分成三部分(和)。接下來就是判斷,我們因爲要求最小值,所以我們要使得左邊的值儘可能的小,這樣最左邊就是最小的。接下來就是找出和的,如果的值小於的值,那麼就將向左邊靠近,即,否則。
/*
* @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;
}