前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >HDU HDOJ 3400 Line belt 解题报告

HDU HDOJ 3400 Line belt 解题报告

作者头像
owent
发布2018-08-01 17:22:41
3460
发布2018-08-01 17:22:41
举报
文章被收录于专栏:owentowent

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3400

这题就是一道简单的两重三分

首先设e点为从ab上离开的点,f为从cd上进入的点

显然对固定点e,f从距c的距离的长度是一个单调函数或者先减后增的函数,这里可以三分算出最优解。这里是第一个三分

然后对e点的最优解易证也存在这个性质,所以再来一个三分,就能解除最优解

代码如下:

代码语言:javascript
复制
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

const double EPS = 1e-10;

typedef struct
{
    double x,y;
}point;

double sulAB(point a, point b, point c, point d, double p, double q, double r);
double sulCD(point e, point c, point d, double q, double r);
double getSulCD(double l,const point &e,const point &c,const point &d,const double &q,const double &r);
double getSulAB(double l,const point &a,const point &b, const point &c,const point &d
    , const double &p,const double &q,const double &r);
double getDis(point a, point b)
{
    return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));
}
int main()
{
    long t,p,q,r;
    double res;
    point a,b,c,d;
    scanf("%ld", &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("%ld %ld %ld", &p, &q, &r);
        res = sulAB(a, b, c, d, p, q, r);
        printf("%.2lf\n", res);
    }
    return 0;
}

double sulAB(point a, point b, point c, point d, double p, double q, double r)
{
    double l,rr,m,mm;
    double tmp1, tmp2;
    l = 0;
    rr = 1.0;
    while(l + EPS < rr)
    {
        m = (l + rr) / 2;
        mm = (m + rr) / 2;
        tmp1 = getSulAB(m, a, b, c, d, p, q, r);
        tmp2 = getSulAB(mm, a, b, c, d, p, q, r);
        if(tmp1 < tmp2)
            rr = mm;
        else
            l = m;
    }

    return getSulAB(l, a, b, c, d, p, q, r);
}

double sulCD(point e, point c, point d, double q, double r)
{
    double l,rr,m,mm;
    double tmp1, tmp2;
    l = 0;
    rr = 1.0;
    while(l + EPS < rr)
    {
        m = (l + rr) / 2;
        mm = (m + rr) / 2;
        tmp1 = getSulCD(m, e, c, d, q, r);
        tmp2 = getSulCD(mm, e, c, d, q, r);
        if(tmp1 < tmp2)
            rr = mm;
        else
            l = m;
    }

    return getSulCD(l, e, c, d, q, r);
}

double getSulCD(double l,const point &e,const point &c,const point &d,const double &q,const double &r)
{
    point p;
    p.x = c.x + (d.x - c.x) * l;
    p.y = c.y + (d.y - c.y) * l;
    return getDis(e, p) / r + getDis(p, d) / q;
}

double getSulAB(double l,const point &a,const point &b, const point &c,const point &d
    , const double &p,const double &q,const double &r)
{
    point pp;
    pp.x = a.x + (b.x - a.x) * l;
    pp.y = a.y + (b.y - a.y) * l;
    return getDis(a, pp) / p + sulCD(pp, c, d, q, r);
}
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2010-05-03,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档