链接:https://www.luogu.org/problemnew/show/P2571
题目描述
在一个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位
输入输出样例
说明
对于100%的数据,1<= Ax,Ay,Bx,By,Cx,Cy,Dx,Dy<=1000
1<=P,Q,R<=10
题解:
三分套。
• 首先如果确定了 AB 上从哪个点离开,那么 上从哪个点离开,那么 上从哪个点离开,那么 CD 上点的 上点的 距离函数一定是个单谷,可以三分来求。
• 如何求解 AB 上的点呢?
• 他也满足单谷的性质,可以三分来求。用CD上的点来更新AB上的点
#include<bits/stdc++.h> using namespace std; const double eps = 1e-6; double Ax, Ay, Bx, By, Cx, Cy, Dx, Dy, p, q, r; double dis(double x1, double y1, double x2, double y2){ return sqrt((x1-x2)*(x1-x2) + (y1-y2)*(y1-y2)); } double work(double nx, double ny){ double lf = Cx, rg = Dx, hlf = Cy, hrg = Dy, ans = 1000000008; while(1){ double midx = (lf + rg) / 2, midy = (hlf + hrg) / 2; double midxm = (midx + rg) / 2, midym = (midy + hrg) / 2; double tmp1 = dis(nx, ny, midx, midy)/r + dis(Ax, Ay, nx, ny)/ p + dis(midx, midy, Dx, Dy)/q; double tmp2 = dis(nx, ny, midxm, midym)/r + dis(Ax, Ay, nx, ny)/ p + dis(midxm, midym, Dx, Dy)/q; if(tmp1 < tmp2) rg = midxm, hrg = midym; else lf = midx, hlf = midy; ans = min(ans, min(tmp1, tmp2)); // printf("%lf %lf ", tmp1, tmp2); if(fabs(midx-midxm) < eps && fabs(midy-midym) < eps)break; } return ans; } int main(){ double ans = 100000000008; scanf("%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf%lf", &Ax, &Ay, &Bx, &By, &Cx, &Cy, &Dx, &Dy, &p, &q, &r); double lf = Ax, rg = Bx, hlf = Ay, hrg = By; while(1){ double midx = (lf + rg) / 2, midy = (hlf + hrg) / 2; double midxm = (midx + rg) / 2, midym = (midy + hrg) / 2; double ans1 = work(midx, midy), ans2 = work(midxm, midym); if(ans1 < ans2) rg = midxm, hrg = midym; else lf = midx, hlf = midy; ans = min(ans, min(ans1, ans2)); if(fabs(midx-midxm) < eps && fabs(midy-midym) < eps)break; } printf("%.2lf ", ans); }