• HDU 3400 Line belt (三分套三分)


    http://acm.split.hdu.edu.cn/showproblem.php?pid=3400

    题意:

    有两条带子ab和cd,在ab上的速度为p,在cd上的速度为q,在其它地方的速度为r。现在计算从a出发到达d的最少花费时间。

    思路:

    分别在ab和cd两段线路上找一个转折点,然后就是由这三段路组成。

    设ab上的线路长度为x,cd上的为y,其余为z。

    那么总的时间就是,分开来考虑,,F(x)是个单调递增函数,G(y,z)是个凹性函数。

    那么总的T函数还是一个凹性函数,那么就可以三分了,对ab进行一次三分,然后继续对cd进行三分。

     1 #include<iostream>
     2 #include<algorithm>
     3 #include<cstring>
     4 #include<cstdio>
     5 #include<vector>
     6 #include<stack>
     7 #include<queue>
     8 #include<cmath>
     9 #include<map>
    10 #include<set>
    11 using namespace std;
    12 typedef long long ll;
    13 typedef pair<int,int> pll;
    14 const int INF = 0x3f3f3f3f;
    15 const int maxn = 300000+5;
    16 
    17 const double eps=1e-8;
    18 
    19 struct node
    20 {
    21     double x,y;
    22 }a,b,c,d;
    23 
    24 double p,q,r;
    25 
    26 double getdis(node t1, node t2)
    27 {
    28     return sqrt((t2.y-t1.y)*(t2.y-t1.y)+(t2.x-t1.x)*(t2.x-t1.x));
    29 }
    30 
    31 double solve_cd(node ab)
    32 {
    33     node mid, midd;
    34     node t1=c,t2=d;
    35     double d1,d2;
    36     do
    37     {
    38         mid.x=(t1.x+t2.x)/2;
    39         mid.y=(t1.y+t2.y)/2;
    40         midd.x=(mid.x+t2.x)/2;
    41         midd.y=(mid.y+t2.y)/2;
    42         d1=getdis(mid,ab)/r+getdis(d,mid)/q;
    43         d2=getdis(midd,ab)/r+getdis(d,midd)/q;
    44         if(d1<d2)  t2=midd;
    45         else t1=mid;
    46     }while(getdis(t1,t2)>=eps);
    47     return min(d1,d2);
    48 }
    49 
    50 double solve_ab()
    51 {
    52     node mid, midd;
    53     node t1=a,t2=b;
    54     double ans1,ans2;
    55     do
    56     {
    57         mid.x=(t1.x+t2.x)/2;
    58         mid.y=(t1.y+t2.y)/2;
    59         midd.x=(mid.x+t2.x)/2;
    60         midd.y=(mid.y+t2.y)/2;
    61         double d1=getdis(mid,a);
    62         double d2=getdis(midd,a);
    63         ans1=d1/p+solve_cd(mid);
    64         ans2=d2/p+solve_cd(midd);
    65         if(ans1<ans2) t2=midd;
    66         else  t1=mid;
    67     }while(getdis(t1,t2)>=eps);
    68     return min(ans1,ans2);
    69 }
    70 
    71 int main()
    72 {
    73     //freopen("in.txt","r",stdin);
    74     int T;
    75     scanf("%d",&T);
    76     while(T--)
    77     {
    78         scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&a.x,&a.y,&b.x,&b.y,&c.x,&c.y,&d.x,&d.y);
    79         scanf("%lf%lf%lf",&p,&q,&r);
    80         printf("%.2f
    ",solve_ab());
    81     }
    82     return 0;
    83 }
  • 相关阅读:
    UNIX环境高级编程——Linux终端设备详解
    UNIX网络编程——网络IPC:套接字
    UNIX网络编程——Socket通信原理和实践
    UNIX环境高级编程——单实例的守护进程
    UNIX环境高级编程——初始化一个守护进程
    UNIX环境高级编程——创建孤儿进程
    UNIX环境高级编程——实现uid to name
    UNIX环境高级编程——标准IO-实现查看所有用户
    自考-数据库及应用
    自考-数据库及应用
  • 原文地址:https://www.cnblogs.com/zyb993963526/p/7679178.html
Copyright © 2020-2023  润新知