您的位置:首页 > 其它

[BZOJ1857][Scoi2010]传送带(三分套三分+计算几何)

2017-01-05 19:50 357 查看

题目描述

传送门

题解

感觉一下好像在传送带上走的太多或者走得太少时间都不是最优的

实际上答案对走的长短单峰

然后就三分套三分…

注意:

①find中的ans一定要有初始值,防止根本不进行三分直接退出

②检查分母不能为0

代码

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;

const double eps=1e-9;
int dcmp(double x)
{
if (x<=eps&&x>=-eps) return 0;
return (x>0)?1:-1;
}
struct Vector
{
double x,y;
Vector(double X=0,double Y=0)
{
x=X,y=Y;
}
};
typedef Vector Point;
Vector operator + (Vector a,Vector b) {return Vector(a.x+b.x,a.y+b.y);}
Vector operator - (Vector a,Vector b) {return Vector(a.x-b.x,a.y-b.y);}
Vector operator * (Vector a,double b) {return Vector(a.x*b,a.y*b);}

Point a,b,c,d;
double p,q,r,ans;

double Dot(Vector a,Vector b)
{
return a.x*b.x+a.y*b.y;
}
double Len(Vector a)
{
return sqrt(Dot(a,a));
}
double calc(double dis1,double dis2)
{
Vector v,w;
Point e,f;
double dis3,t;

v=b-a,w=c-d;
if (dcmp(Len(v))) v=v*(dis1/Len(v));e=a+v;
if (dcmp(Len(w))) w=w*(dis2/Len(w));f=d+w;
dis3=Len(f-e);
t=dis1/p+dis2/q+dis3/r;
return t;
}
double find2(double dis)
{
double l=0,r=Len(d-c),mid1,mid2,ans1,ans2,ans=0;
while (dcmp(r-l)>0)
{
mid1=l+(r-l)/3.0;
mid2=r-(r-l)/3.0;
ans1=calc(dis,mid1);
ans2=calc(dis,mid2);
if (dcmp(ans1-ans2)<=0) ans=mid1,r=mid2;
else l=mid1;
}
return calc(dis,ans);
}
double find1()
{
double l=0,r=Len(b-a),mid1,mid2,ans1,ans2,ans=0;
while (dcmp(r-l)>0)
{
mid1=l+(r-l)/3.0;
mid2=r-(r-l)/3.0;
ans1=find2(mid1);
ans2=find2(mid2);
if (dcmp(ans1-ans2)<=0) ans=mid1,r=mid2;
else l=mid1;
}
return find2(ans);
}
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);
ans=find1();
printf("%.2lf\n",ans);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: