HDU3400 三分经典(速度决策)

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;
}

猜你喜欢

转载自blog.csdn.net/Feynman1999/article/details/80053330
今日推荐