轉載請註明出處,謝謝http://blog.csdn.net/acm_cxlove/article/details/7854526
by---cxlove
題目:有一個直角彎道,兩條路的寬分別為x,y,汽車的長為l,寬為w,問能否轉過去。
用一個別人的圖:
我們 將車子盡量靠在右邊和下邊的邊界,以右下角為座標原點,建立座標系,寫出車子的內邊界的直線方程
即圖中所示,斜率確定,然後上移。
那麼這樣就可以得到P點座標,將Y=x代入,得到x/tan(a)-l/cos(a)-w*sin(a)。
我們只要求出最小值,如果大於-y便 可以轉過去。
分析這個函數,首先求一次導
f’=l/cos^2(a)-x/sin^2(a)-w*cos(a),沒有明顯的單調性。再求一次導
f''=2*l*sin(a)/cos^3(a)+2*x*cos(a)/sin^3(a)+w*sin(a)。
由於角度在0-90度之間,所以二階導非負,為凹函數,三分求最小值。
注意還得特判初始寬度是否能夠容納
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#define eps 1e-7using namespace std;double x,y,l,w;double cal(double a){ return (x-l*sin(a)-w/cos(a))/tan(a);}int main(){ while(scanf("%lf%lf%lf%lf",&x,&y,&l,&w)!=EOF){ double low=0,high=acos(-1.0)/2,mid,midd; while(fabs(high-low)>eps){ mid=(low+high)/2; midd=(mid+high)/2; if(cal(mid)<cal(midd)) high=midd; else low=mid; } if(cal(low)<-y||x<w||y<w) puts("no"); else puts("yes"); } return 0;}