HDU 3400 Line belt (三分套三分)

时间:2023-03-09 15:32:28
HDU 3400 Line belt (三分套三分)

http://acm.split.hdu.edu.cn/showproblem.php?pid=3400

题意:

有两条带子ab和cd,在ab上的速度为p,在cd上的速度为q,在其它地方的速度为r。现在计算从a出发到达d的最少花费时间。

思路:

分别在ab和cd两段线路上找一个转折点,然后就是由这三段路组成。

设ab上的线路长度为x,cd上的为y,其余为z。

那么总的时间就是HDU 3400 Line belt (三分套三分),分开来考虑,HDU 3400 Line belt (三分套三分),F(x)是个单调递增函数,G(y,z)是个凹性函数。

那么总的T函数还是一个凹性函数,那么就可以三分了,对ab进行一次三分,然后继续对cd进行三分。

 #include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<vector>
#include<stack>
#include<queue>
#include<cmath>
#include<map>
#include<set>
using namespace std;
typedef long long ll;
typedef pair<int,int> pll;
const int INF = 0x3f3f3f3f;
const int maxn = +; const double eps=1e-; struct node
{
double x,y;
}a,b,c,d; double p,q,r; double getdis(node t1, node t2)
{
return sqrt((t2.y-t1.y)*(t2.y-t1.y)+(t2.x-t1.x)*(t2.x-t1.x));
} double solve_cd(node ab)
{
node mid, midd;
node t1=c,t2=d;
double d1,d2;
do
{
mid.x=(t1.x+t2.x)/;
mid.y=(t1.y+t2.y)/;
midd.x=(mid.x+t2.x)/;
midd.y=(mid.y+t2.y)/;
d1=getdis(mid,ab)/r+getdis(d,mid)/q;
d2=getdis(midd,ab)/r+getdis(d,midd)/q;
if(d1<d2) t2=midd;
else t1=mid;
}while(getdis(t1,t2)>=eps);
return min(d1,d2);
} double solve_ab()
{
node mid, midd;
node t1=a,t2=b;
double ans1,ans2;
do
{
mid.x=(t1.x+t2.x)/;
mid.y=(t1.y+t2.y)/;
midd.x=(mid.x+t2.x)/;
midd.y=(mid.y+t2.y)/;
double d1=getdis(mid,a);
double d2=getdis(midd,a);
ans1=d1/p+solve_cd(mid);
ans2=d2/p+solve_cd(midd);
if(ans1<ans2) t2=midd;
else t1=mid;
}while(getdis(t1,t2)>=eps);
return min(ans1,ans2);
} int main()
{
//freopen("in.txt","r",stdin);
int T;
scanf("%d",&T);
while(T--)
{
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",&p,&q,&r);
printf("%.2f\n",solve_ab());
}
return ;
}