BZOJ1857 傳送帶(三分套三分(難道是傳說中的。。。九分!))
阿新 • • 發佈:2018-12-14
【題目描述】
在一個2維平面上有兩條傳送帶,每一條傳送帶可以看成是一條線段。兩條傳送帶分別為線段AB和線段CD。lxhgww在AB上的移動速度為P,在CD上的移動速度為Q,在平面上的移動速度R。現在lxhgww想從A點走到D點,他想知道最少需要走多長時間。
【輸入格式】
輸入資料第一行是4個整數,表示A和B的座標,分別為Ax,Ay,Bx,By
第二行是4個整數,表示C和D的座標,分別為Cx,Cy,Dx,Dy
第三行是3個整數,分別是P,Q,R
【輸出格式】
輸出資料為一行,表示lxhgww從A點走到D點的最短時間,保留到小數點後2位
【樣例輸入】
0 0 0 100
100 0 100 100
2 2 1
【備註】
對於100%的資料,1<= Ax,Ay,Bx,By,Cx,Cy,Dx,Dy<=1000 1<=P,Q,R<=10
【題目分析】
首先%一下用模擬退火和粒子群演算法的大佬(反正我兩個都不會)
然後就是網上大部分的做法:三分套三分。
如果固定一邊,那麼另一邊肯定跑的是一個單峰函式,但如果兩條不定。。。。。我也不會證為什麼三分套三分是對的。。。(能A就靠看題解)直接貼程式碼,感性理解一下。。。。
【程式碼~】
#include<bits/stdc++.h> using namespace std; const double eps=1e-8; double ax,ay,bx,by,cx,cy,dx,dy,p,q,r; double dist(double a,double b,double c,double d) { double disx=a-c,disy=b-d; return sqrt(disx*disx+disy*disy); } double js(double a,double b,double c,double d) { return dist(a,b,c,d)/r+dist(c,d,dx,dy)/q; } double sf1(double x,double y) { double lx=cx,ly=cy,rx=dx,ry=dy; while(dist(lx,ly,rx,ry)>eps) { double tmpx=(rx-lx)/3,tmpy=(ry-ly)/3; double lmidx=lx+tmpx,rmidx=rx-tmpx,lmidy=ly+tmpy,rmidy=ry-tmpy; double ans1=js(x,y,lmidx,lmidy); double ans2=js(x,y,rmidx,rmidy); if(ans2-ans1>eps) rx=rmidx,ry=rmidy; else lx=lmidx,ly=lmidy; } return js(x,y,lx,ly); } double sf2() { double lx=ax,ly=ay,rx=bx,ry=by; while(dist(lx,ly,rx,ry)>eps) { double tmpx=(rx-lx)/3,tmpy=(ry-ly)/3; double lmidx=lx+tmpx,rmidx=rx-tmpx,lmidy=ly+tmpy,rmidy=ry-tmpy; double ans1=sf1(lmidx,lmidy)+dist(ax,ay,lmidx,lmidy)/p; double ans2=sf1(rmidx,rmidy)+dist(ax,ay,rmidx,rmidy)/p; if(ans2-ans1>eps) rx=rmidx,ry=rmidy; else lx=lmidx,ly=lmidy; } return sf1(lx,ly)+dist(ax,ay,lx,ly)/p; } int main() { scanf("%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf",&ax,&ay,&bx,&by,&cx,&cy,&dx,&dy,&p,&q,&r); printf("%.2lf\n",sf2()); return 0; }