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;
}
posted @ 2025-11-28 22:15  屈臣  阅读(5)  评论(0)    收藏  举报