題目
Problem 947: 傳送帶
Time Limit: 1000 ms Memory Limit: 256000 KBProblem Description
在一個2維平面上有兩條傳送帶,每一條傳送帶可以看成是一條線段。兩條傳送帶分別爲線段AB和線段CD。FTD在AB上的移動速度爲P,在CD上的移動速度爲Q,在平面上的移動速度R。現在FTD想從A點走到D點,他想知道最少需要走多長時間。
Input
輸入數據第一行是4個整數,表示A和B的座標,分別爲Ax,Ay,Bx,By 第二行是4個整數,表示C和D的座標,分別爲Cx,Cy,Dx,Dy 第三行是3個整數,分別是P,Q,R
Output
輸出數據爲一行,表示lxhgww從A點走到D點的最短時間,保留到小數點後2位
Sample Input
0 0 0 100
100 0 100 100
2 2 1Sample Output
136.60對於100%的數據
1<=Ax,Ay,Bx,By,Cx,Cy,Dx,Dy<=1000
1<=P,Q,R<=10Problem Source
NOIP2017多校聯測&提高組模擬16
分析
- 我們發現,對於一條線段,從一端點到中間一點再出去到外面某一點,隨着中間那個點的變化,得到的時間會是一個單峯函數(當然有可能最值會超出這條線段,但也不影響三分)
- 對兩條線段都三分,(三分套三分),即先三分 AB 的離開點,在這基礎上求出 CD 上的最小時間。
程序
#include <cstdio>
#include <cmath>
using namespace std;
struct zzk{double x,y;} A,B,C,D,L,R,M1,M2,m1,m2,l,r;
double ans,ret,PP,QQ,RR,F1,F2,f1,f2;
int i,j;
double dis(zzk x,zzk y){return sqrt((x.x-y.x)*(x.x-y.x)+(x.y-y.y)*(x.y-y.y));}
double f(zzk x){
for (l=C,r=D,j=1; j<=100; j++){
m1=(zzk){l.x+(r.x-l.x)/3,l.y+(r.y-l.y)/3},m2=(zzk){l.x+(r.x-l.x)*2/3,l.y+(r.y-l.y)*2/3};
f1=dis(A,x)/PP+dis(x,m1)/RR+dis(m1,D)/QQ;
f2=dis(A,x)/PP+dis(x,m2)/RR+dis(m2,D)/QQ;
if (f1<f2){r=m2; ret=f1; continue;}
l=m1; ret=f2;
}
return ret;
}
int main(){
scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&A.x,&A.y,&B.x,&B.y,&C.x,&C.y,&D.x,&D.y);
scanf("%lf%lf%lf",&PP,&QQ,&RR);
for (L=A,R=B,i=1; i<=0; i++){
M1=(zzk){L.x+(R.x-L.x)/3,L.y+(R.y-L.y)/3},M2=(zzk){L.x+(R.x-L.x)*2/3,L.y+(R.y-L.y)*2/3};
F1=f(M1);
F2=f(M2);
if (F1<F2){R=M2; ans=F1; continue;}
L=M1; ans=F2;
}
printf("%.2f",ans);
}
提示
- 之前都是二分,直接
m=(l+r)/1
,而這次第一次打三分,應該是m1=l+(r-l)/3,m2=l+(r-l)*2/3
,而一開始我直接(l+r)/3
了,結果WA了……