題目描述 如題,給出一個N次函數,保證在範圍[l,r]記憶體在一點x,使得[l,x]上單調增,[x,r]上單調減。試求出x的值。 輸入輸出格式 輸入格式: 第一行一次包含一個正整數N和兩個實數l、r,含義如題目描述所示。 第二行包含N+1個實數,從高到低依次表示該N次函數各項的繫數。 輸出格式: 輸出 ...
題目描述
如題,給出一個N次函數,保證在範圍[l,r]記憶體在一點x,使得[l,x]上單調增,[x,r]上單調減。試求出x的值。
輸入輸出格式
輸入格式:
第一行一次包含一個正整數N和兩個實數l、r,含義如題目描述所示。
第二行包含N+1個實數,從高到低依次表示該N次函數各項的繫數。
輸出格式:
輸出為一行,包含一個實數,即為x的值。四捨五入保留5位小數。
輸入輸出樣例
輸入樣例#1:3 -0.9981 0.5 1 -3 -3 1輸出樣例#1:
-0.41421
說明
時空限制:50ms,128M
數據規模:
對於100%的數據:7<=N<=13
樣例說明:
如圖所示,紅色段即為該函數f(x)=x^3-3x^2-3x+1在區間[-0.9981,0.5]上的圖像。
當x=-0.41421時圖像位於最高點,故此時函數在[l,x]上單調增,[x,r]上單調減,故x=-0.41421,輸出-0.41421。
題解:
裸三分。
在[L,R]中,
取a=(R-L)/3+L,b=(R-L)/3*2+L。
如果f(a)>f(b)
則答案在[L,b]里(如果在[b, R]里,則[a, b]段遞增),
如果f(a)<f(b)
則答案在[a,R]里(如果在[L, a]里,則[a, b]段遞減),
遞歸或迴圈即可。
1 #include<cstdio> 2 #include<cstring> 3 #include<iostream> 4 #include<algorithm> 5 #include<cmath> 6 using namespace std; 7 double l,r,xs[23];int n; 8 double f(double x){ 9 double ans=0; 10 for(int i=1;i<=n;i++){ 11 double tmp=xs[i]; 12 for(int j=1;j<=n-i+1;j++) tmp*=x; 13 ans+=tmp; 14 } 15 return ans+xs[n+1]; 16 } 17 int main(){ 18 scanf("%d",&n); 19 scanf("%lf%lf",&l,&r); 20 for(int i=1;i<=n+1;i++) scanf("%lf",&xs[i]); 21 double lx=l,rx=r; 22 while(abs(lx-rx)>0.000001){ 23 double x1=(rx-lx)/3+lx,x2=(rx-lx)/3*2+lx; 24 if(f(x1)>f(x2)) rx=x2; 25 else lx=x1; 26 } 27 printf("%.5f\n",lx); 28 return 0; 29 }