D-Keiichi Tsuchiya the Drift King 2018焦作 解析幾何
阿新 • • 發佈:2018-12-15
題目連結:哆啦A夢傳送門
題意:給出寬為a,長為b的車,有一條半徑為r,角度為d的拐彎軌道,讓你求出軌道的寬度,滿足儘可能的小。
題解:
我們先上幅圖:
看著這幅圖說話,題目又說,車是沿著軌道相切著漂移的,我們要想軌道盡可能的小,其實只是以車左下角頂點D為基準,繞原點O旋轉的,當D點旋轉到以原點O成水平線之後,軌道距離已經固定好了,就以半徑為OD旋轉,是的,我們這裡說的是水平線之後,那麼之前的呢?我們還不確定,因為水平線之前的軌道距離肯定比OD小,看圖就知道了,當我們旋轉的角度是,這個就是題目說的d(因為是整體漂移的),而移到水平線的角度是,那麼移到D' ,顯然軌道距離小於OD,那麼我們要求此時的軌道距離,只要知道距離s就行了,我們將OD-s就是最後的結果,根據題目給的資料,
我們角可以很容易求出,, 長度 t 由余弦定理可以很容易求出。
角和長度t 都知道了,那麼在直角三角形,顯然最終的答案就是 。
程式碼所示:
#include<cstdio> #include<algorithm> #include<cstring> #include<cmath> using namespace std; const double PI=acos(-1.0); const double esp=1e-10; int dcmp(double x) { if(fabs(x)<esp) return 0; else return x<0?-1:1; } int main() { int ncase; scanf("%d",&ncase); while(ncase--) { double a,b,r,d; scanf("%lf%lf%lf%lf",&a,&b,&r,&d); double maxl=sqrt(b*b+(a+r)*(a+r)); d=d*PI/180; ///轉化成弧度 double anglemax=asin(b/maxl); ///求出beita if(dcmp(d-anglemax)>=0) printf("%.12f\n",maxl-r); ///說明移動後的點D'在水平線之後,故直接輸出就行了 else{ double angle=anglemax-d; ///餘弦定理求距離t double t=sqrt(maxl*maxl*2-2*maxl*maxl*cos(angle)); ///求角度afa double co=angle/2; double s=t*sin(co); // printf("t=%f,angle=%f,s=%f,co=%f\n",t,angle,s,co); printf("%.12f\n",maxl-r-s);///減去s就行了 } } return 0; }