1. 程式人生 > >洛谷 P1883 函數

洛谷 P1883 函數

交點 可能 data 小數 四舍五入 最值 ace 2.0 輸出格式

P1883 函數

題目描述

給定n個二次函數f1(x),f2(x),...,fn(x)(均形如ax^2+bx+c),設F(x)=max{f1(x),f2(x),...,fn(x)},求F(x)在區間[0,1000]上的最小值。

輸入輸出格式

輸入格式:

輸入第一行為正整數T,表示有T 組數據。

每組數據第一行一個正整數n,接著n行,每行3個整數a,b,c ,用來表示每個二次函數的3個系數,註意二次函數有可能退化成一次。

輸出格式:

每組數據輸出一行,表示F(x)的在區間[0,1000]上的最小值。答案精確到小數點後四位,四舍五入。

輸入輸出樣例

輸入樣例#1: 復制
2
1
2 0 0
2
2 0 0
2 -4 2
輸出樣例#1: 復制
0.0000
0.5000

說明

【數據範圍】

T < 10, n ≤ 10000,0 ≤ a ≤ 100,|b| ≤ 5000, |c| ≤ 5000 前50%數據n ≤ 100

/*最小值一定在交點處取得,如果枚舉交點,
是O(n^2)的復雜度,應該能過50%的點。
AC思路:觀察圖像,因為a都是大於等於0的,所以F(x)的
圖像是一個特殊的凹函數,然後這個題目就變成
了求函數最值,然後就可以想到用三分法。 
*/ #include<cstdio> #include<cstring> #include<iostream> #include<algorithm> using namespace std; int T,n; double l,r,mid1,mid2; double a[10001],b[10001],c[10001]; double f(double aa,double bb,double cc,double x){ return x*x*aa+x*bb+cc; } double F(double x){ double
bns=-0x3f3f3f3f; for(int i=1;i<=n;i++) bns=max(bns,f(a[i],b[i],c[i],x)); return bns; } int main(){ scanf("%d",&T); while(T--){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lf%lf%lf",&a[i],&b[i],&c[i]); l=0.00;r=1000.00; while(r-l>=0.0000000001){ mid1=(2.0*l+r)/3.0; mid2=(l+2.0*r)/3.0; /* double x1=F(mid1); double x2=F(mid2);*/ if(F(mid1)>F(mid2)) l=mid1; else r=mid2; } printf("%.4lf\n",F(l)); } }

洛谷 P1883 函數