【来源】
SCOI-2010
一本通题库-1439
LibreOJ-10017
BZOJ-1857
vjudge
【题目描述】
在一个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
【样例输出】
136.60
【数据范围】
对于100%的数据,1<= Ax,Ay,Bx,By,Cx,Cy,Dx,Dy<=1000。
1<=P,Q,R<=10。
【解析】
三分套三分。
考虑将其中一个点固定,那么对于另一个点用三分可求出这个点的位置。
该点有最小值,它的左右两点都比他大,所以是单峰函数。
那么对于最开始的点,我们同样也是单峰函数,也可以三分。
【代码】
#pragma GCC optimize(3,"Ofast","inline")
#pragma G++ optimize(3,"Ofast","inline")
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <algorithm>
#define RI register int
#define re(i,a,b) for(RI i=a; i<=b; i++)
#define ms(i,a) memset(a,i,sizeof(a))
#define MAX(a,b) (((a)>(b)) ? (a):(b))
#define MIN(a,b) (((a)<(b)) ? (a):(b))
#define sqr(a) (a)*(a)
using namespace std;
typedef long long LL;
const int N=105;
const int inf=1e9;
const double eps=1e-12;
double xa,ya,xb,yb,xc,yc,xd,yd,p,q,r;
inline double calc(double x1,double y1,double x2,double y2) {
return sqrt(sqr(x1-x2)+sqr(y1-y2));
}
double check(double x,double y) {
double xl=xc,yl=yc,xr=xd,yr=yd;
while(fabs(xr-xl)>eps || fabs(yr-yl)>eps) {
double xmid1=xl+(xr-xl)/3;
double ymid1=yl+(yr-yl)/3;
double xmid2=xr-(xr-xl)/3;
double ymid2=yr-(yr-yl)/3;
double ans1=calc(xa,ya,x,y)/p+calc(x,y,xmid1,ymid1)/r+calc(xmid1,ymid1,xd,yd)/q;
double ans2=calc(xa,ya,x,y)/p+calc(x,y,xmid2,ymid2)/r+calc(xmid2,ymid2,xd,yd)/q;
if(ans1<ans2) xr=xmid2,yr=ymid2;
else xl=xmid1,yl=ymid1;
}
double ret=calc(xa,ya,x,y)/p+calc(x,y,xl,yl)/r+calc(xl,yl,xd,yd)/q;
return ret;
}
int main() {
scanf("%lf%lf%lf%lf",&xa,&ya,&xb,&yb);
scanf("%lf%lf%lf%lf",&xc,&yc,&xd,&yd);
scanf("%lf%lf%lf",&p,&q,&r);
double xl=xa,yl=ya,xr=xb,yr=yb;
while(fabs(xr-xl)>eps || fabs(yr-yl)>eps) {
double xmid1=xl+(xr-xl)/3;
double ymid1=yl+(yr-yl)/3;
double xmid2=xr-(xr-xl)/3;
double ymid2=yr-(yr-yl)/3;
if(check(xmid1,ymid1)<check(xmid2,ymid2)) xr=xmid2,yr=ymid2;
else xl=xmid1,yl=ymid1;
}
printf("%0.2lf\n",check(xl,yl));
return 0;
}