• 博客园logo
  • 会员
  • 众包
  • 新闻
  • 博问
  • 闪存
  • 赞助商
  • HarmonyOS
  • Chat2DB
    • 搜索
      所有博客
    • 搜索
      当前博客
  • 写随笔 我的博客 短消息 简洁模式
    用户头像
    我的博客 我的园子 账号设置 会员中心 简洁模式 ... 退出登录
    注册 登录
L&King
有何不可!
   首页    新随笔    联系   管理    订阅  订阅

HDU 3400 Line belt【三分套三分】

从A出发到D,必定有从AB某个点E出发,从某个点F进入CD

故有E,F两个不确定的值。

在AB上行走的时间     f = AE / p

在其他区域行走的时间  g = EF / r

在CD上行走的时间     h = FD / q

总时间 T = f + g + h

当E确定时,T1 = g + h + C   此时g时一个先减后增的凹函数,h是一个单调递减的凹函数,根据凹函数的性质,故T1是一个凹函数

反之亦然,故需要三分确定其中一个点的位置,再三分另一个点的位置。

#include<stdio.h>
#include<string.h>
#include<math.h>
const double eps=1e-8;
struct node{
    double x,y;
}a,b,c,d,e,f;
double p,q,r;
double dis(node A,node B){
    double x=A.x-B.x;
    double y=A.y-B.y;
    return sqrt(x*x+y*y);
}
double cal(double bi){
    f.x=c.x+(d.x-c.x)*bi;
    f.y=c.y+(d.y-c.y)*bi;
    return dis(e,f)/r+dis(f,d)/q;
}
double find2(double bi){
    e.x=a.x+(b.x-a.x)*bi;
    e.y=a.y+(b.y-a.y)*bi;
    double l=0,r=1,mid,mmid;
    while(r-l>eps){
        mid=(l+r)/2;
        mmid=(mid+r)/2;
        if(cal(mid)<cal(mmid))
            r=mmid;
        else
            l=mid;
    }
    return cal(l)+dis(a,e)/p;
}
double find1(){
    double l=0,r=1,mid,mmid;
    while(r-l>eps){
        mid=(l+r)/2;
        mmid=(mid+r)/2;
        if(find2(mid)<find2(mmid))
            r=mmid;
        else
            l=mid;
    }
    return find2(l);
}
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);
        printf("%.2f\n",find1());
    }
    return 0;
}

 

posted @ 2016-07-27 10:31  L&King  阅读(176)  评论(0)    收藏  举报
刷新页面返回顶部
博客园  ©  2004-2025
浙公网安备 33010602011771号 浙ICP备2021040463号-3