1857: [Scoi2010]传送带
Time Limit: 1 Sec Memory Limit: 64 MB
Submit: 737 Solved: 387
[Submit][Status][Discuss]
Description
在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段。两条传送带分别为线段AB和线段CD。lxhgww在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度R。现在lxhgww想从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 1
Sample Output
136.60
HINT
对于100%的数据,1<= Ax,Ay,Bx,By,Cx,Cy,Dx,Dy<=1000
1<=P,Q,R<=10
Source
Day2
三分套三分。
首先如果确定了AB上从哪个点离开,那么CD上点的距离函数一定是一个单谷函数,可以三分来求。
如何求解AB上的点呢?
他也满足单谷的性质(然而并不会证明),可以三分来求。
所以就是三分套三分了。
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#define eps 1e-5
using namespace std;
struct Point
{
double x,y;
friend Point operator +(Point a,Point b)
{
return (Point){a.x+b.x,a.y+b.y};
}
friend Point operator -(Point a,Point b)
{
return (Point){a.x-b.x,a.y-b.y};
}
friend Point operator /(Point a,int k)
{
return (Point){(double)a.x/k,(double)a.y/k};
}
}a,b,c,d;
double P,Q,R;
double Sqr(double x)
{
return x*x;
}
double Dis(Point x,Point y)
{
return sqrt(Sqr(x.x-y.x)+Sqr(x.y-y.y));
}
double Get(Point ab,Point cd)
{
return Dis(a,ab)/P+Dis(ab,cd)/R+Dis(cd,d)/Q;
}
double Calc(Point x)
{
Point l=c,r=d;
while (fabs(l.x-r.x)>eps||fabs(l.y-r.y)>eps)
{
Point m=l+(r-l)/3,mm=r-(r-l)/3;
double am=Get(x,m),amm=Get(x,mm);
if (am<amm) r=mm;
else l=m;
}
return Get(x,l);
}
int main()
{
scanf("%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y);
scanf("%lf%lf%lf%lf",&c.x,&c.y,&d.x,&d.y);
scanf("%lf%lf%lf",&P,&Q,&R);
Point l=a,r=b;
while (fabs(l.x-r.x)>eps||fabs(l.y-r.y)>eps)
{
Point m=l+(r-l)/3,mm=r-(r-l)/3;
double am=Calc(m),amm=Calc(mm);
if (am<amm)
r=mm;
else l=m;
}
printf("%.2lf\n",Calc(l));
return 0;
}
时间: 2024-10-29 19:05:53