problem
In a two-dimensional plane there are two line belts, there are two segments AB and CD, lxhgww’s speed on AB is P and on CD is Q, he can move with the speed R on other area on the plane.
How long must he take to travel from A to D?
Input
The first line is the case number T.
For each case, there are three lines.
The first line, four integers, the coordinates of A and B: Ax Ay Bx By.
The second line , four integers, the coordinates of C and D:Cx Cy Dx Dy.
The third line, three integers, P Q R.
0<= Ax,Ay,Bx,By,Cx,Cy,Dx,Dy<=1000
1<=P,Q,R<=10
Output
The minimum time to travel from A to D, round to two decimals.
Sample Input
1
0 0 0 100
100 0 100 100
2 2 1
Sample Output
136.60
思路
显然考察函数的单调性
可以发现当在ab上所走长度固定时,从cd上哪点进入是单峰函数
由于精度是0.01 且数在1e3 于是可以枚举+三分
这种做法很不优秀,虽然可以ac
(进一步考虑,可以三分套三分,Tloglog很优秀)
思路相同,见代码示例2
代码示例1
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int debug_num=0;
const double eps=1e-5;
#define debug cout<<"debug "<<++debug_num<<" :"
double ax,ay;
double bx,by;
double cx,cy;
double dx,dy;
double p,q,r;
double x,y;
double dis(double ax,double ay,double bx,double by)
{
return sqrt((ax-bx)*(ax-bx)+(ay-by)*(ay-by));
}
double dis_ab;
double dis_cd;
double fun(double mid)
{
//先求出点xx,yy
double bili=mid/dis_cd;
double xx=dx-(dx-cx)*bili;
double yy=dy-(dy-cy)*bili;
//debug<<x<<" "<<y<<endl;
//debug<<xx<<" "<<yy<<endl;
double t1=dis(x,y,xx,yy)/r;
double t2=mid/q;
//debug<<t1<<" "<<t2<<endl;
return t1+t2;
}
int main()
{
int num;
int t;
//freopen("in.txt","r",stdin);
//ios::sync_with_stdio(false);
scanf("%d",&t);
while(t--)
{
scanf("%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf ",
&ax,&ay,&bx,&by,&cx,&cy,&dx,&dy,&p,&q,&r);
dis_ab=dis(ax,ay,bx,by);
dis_cd=dis(cx,cy,dx,dy);
//debug<<dis_cd<<endl;
num=(int)(max(dis_ab,dis_cd)*100/min(min(p,q),min(q,r)));
double minn=1e8;
int ans=0;
double res;
for(int i=0;i<=num;++i){
x=ax+i*1.0/num*(bx-ax);
y=ay+i*1.0/num*(by-ay);
//debug<<x<<" "<<y<<" ";
double l=0,r=dis_cd;
while(r-l>eps)
{
double mid=(r+l)/2;
double midmid=(mid+r)/2;
double mid_v=fun(mid);
double midmid_v=fun(midmid);
if(mid_v>=midmid_v) l=mid;
else r=midmid;
}
//cout<<r<<" ";
double tmp=fun(r);
if(tmp+i*1.0/num*dis_ab/p<minn) ans=i,res=r;
minn=min(minn,tmp+i*1.0/num*dis_ab/p);
}
//cout<<fun()<<endl;
printf("%.2lf\n",minn);
}
return 0;
}
代码示例2
#include <cstdio>
#include <cstring>
#include <cmath>
#include <iostream>
#include <algorithm>
#include<time.h>
using namespace std;
typedef long long ll;
int debug_num=0;
const double eps=1e-5;
#define debug cout<<"debug "<<++debug_num<<" :"
double ax,ay;
double bx,by;
double cx,cy;
double dx,dy;
double p,q,r;
double x,y;
double dis_ab;
double dis_cd;
inline double dis(double ax,double ay,double bx,double by)
{
return sqrt((ax-bx)*(ax-bx)+(ay-by)*(ay-by));
}
double fun(double bili)
{
double cd_x=dx-bili*(dx-cx);
double cd_y=dy-bili*(dy-cy);
double t1=dis(x,y,cd_x,cd_y)/r;
double t2=bili*dis_cd/q;
return t1+t2;
}
double solve(double bili)
{
x=ax+bili*(bx-ax);
y=ay+bili*(by-ay);
double l=0,r=1.0;
for(int i=0;i<50;++i){
double mid=(2*l+r)/3;
double midmid=(l+2*r)/3;
double mid_v=fun(mid);
double midmid_v=fun(midmid);
if(mid_v>=midmid_v) l=mid;
else r=midmid;
}
return bili*dis_ab/p+fun(r);
}
int main()
{
//freopen("in.txt","r",stdin);
//ios::sync_with_stdio(false);
int t;
scanf("%d",&t);
while(t--)
{
scanf("%lf %lf %lf %lf %lf %lf %lf %lf %lf %lf %lf ",
&ax,&ay,&bx,&by,&cx,&cy,&dx,&dy,&p,&q,&r);
//cin>>ax>>ay>>bx>>by>>cx>>cy>>dx>>dy>>p>>q>>r;
dis_ab=dis(ax,ay,bx,by);
dis_cd=dis(cx,cy,dx,dy);
double l=0.0,r=1;
for(int i=0;i<50;++i){
//cout<<clock()<<endl;
double mid=(2*l+r)/3;
double midmid=(l+2*r)/3;
double mid_v=solve(mid);
double midmid_v=solve(midmid);
if(mid_v>=midmid_v) l=mid;
else r=midmid;
}
printf("%.2f\n",solve(r));
}
return 0;
}