洛谷 P2571 [SCOI2010]传送带 题解

时间:2023-12-01 23:13:38

每日一题 day51 打卡

Analysis

这道题是用非常恶心的三分套三分做的,有一个技巧是不要枚举坐标,枚举两条线段构成三角形的相似比就好了。

了解思路就还挺好写的(尽管我还调了三天)

 #include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define int long long
#define rep(i,s,e) for(register int i=s;i<=e;++i)
#define dwn(i,s,e) for(register int i=s;i>=e;--i)
using namespace std;
inline int read()
{
int x=,f=;
char c=getchar();
while(c<''||c>'') {if(c=='-') f=-; c=getchar();}
while(c>=''&&c<='') {x=x*+c-''; c=getchar();}
return f*x;
}
inline void write(int x)
{
if(x<) {putchar('-'); x=-x;}
if(x>) write(x/);
putchar(x%+'');
}
struct node
{
double x,y;
}a,b,c,d;
double p,q,r;
inline node calc_point(node a,node b,double k)
{
node point;
point.x=(b.x-a.x)*k+a.x;
point.y=(b.y-a.y)*k+a.y;
return point;
}
inline double calc_dis(node a,node b)
{
return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
inline double check_two(double k1,double k2)
{
node point_one=calc_point(a,b,k1),point_two=calc_point(c,d,k2);
double dis1=calc_dis(a,point_one)/p,dis2=calc_dis(point_one,point_two)/r,dis3=calc_dis(point_two,d)/q;
return dis1+dis2+dis3;
}
inline double check_one(double k)
{
double l2=0.0,r2=1.0;
while(r2-l2>1e-)
{
double mid12=l2+(r2-l2)/3.0,mid22=r2-(r2-l2)/3.0;
if(check_two(k,mid12)>check_two(k,mid22)) l2=mid12;
else r2=mid22;
}
return check_two(k,l2);
}
signed 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);
double l1=0.0,r1=1.0;
while(r1-l1>1e-)
{
double mid11=l1+(r1-l1)/3.0,mid21=r1-(r1-l1)/3.0;
if(check_one(mid11)>check_one(mid21)) l1=mid11;
else r1=mid21;
}
printf("%.2lf",check_one(l1));
return ;
}

请各位大佬斧正(反正我不认识斧正是什么意思)