1. 程式人生 > >HDU 3400 兩次三分

HDU 3400 兩次三分

這道題卡了我好久,一直不能證明他們的距離為什麼是先遞減後遞增,所以也不能想到三分

網上也沒有給出證明,嘗試用三分寫了下,注意是三分的E,F點在AB CD點上的佔的比例,這樣程式碼比較簡單好看

#include<stdio.h>
#include<math.h>
#include<string.h>
#define eps 1e-8
struct point
{
       double x,y;
};

point a,b,c,d;
double p,q,r;
double len(point a,point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}

double time(double l,double m)
{
     point e,f;
     e.x=l*(b.x-a.x)+a.x;
     e.y=l*(b.y-a.y)+a.y;
     f.x=m*(d.x-c.x)+c.x;
     f.y=m*(d.y-c.y)+c.y;
     return len(a,e)/p+len(e,f)/r+len(f,d)/q;
}
double ts(double ab)
{
     double ll=0.0,rr=1.0,mid,midmid;
     while(rr-ll>eps)
     {
        mid=(ll+rr)/2.0;
        midmid=(mid+rr)/2.0;
        if(time(ab,mid)<time(ab,midmid))
        rr=midmid;
        else
        ll=mid;
     }
     return time(ab,ll);
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
       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 ll=0.0,rr=1.0;
       while(rr-ll>eps)
       {
           double mid=(rr+ll)/2.0;
           double midmid=(mid+rr)/2.0;
           if(ts(mid)<ts(midmid))
           rr=midmid;
           else
           ll=mid;
       }
       printf("%.2lf\n",ts(ll));
    }
    return 0;
}