zoukankan      html  css  js  c++  java
  • bzoj1038: [ZJOI2008]瞭望塔

    http://www.lydsy.com/JudgeOnline/problem.php?id=1038

    本题可以使用三分法

    将点按横坐标排好序后

    对于任意相邻两个点连成的线段,瞭望塔的高度 是单峰函数,而且是下凸函数

    感性理解单峰就是

    瞭望塔建的靠左,为了能看到右边的,要高一点

    瞭望塔建的靠右,为了能看到左边的,要高一点

    所以

    枚举所有线段,三分线段上建造瞭望塔的位置,所有线段上的瞭望塔高度取最小

    #include<cmath>
    #include<cstdio>
    #include<algorithm>
    
    using namespace std;
    
    #define N 301
    
    const double eps=1e-7;
    
    int n;
    
    struct POINT
    {
        double x,y;
    }e[N];
    
    struct LINE
    {
        double k,b;
        bool exit;
    }l[N];
    
    bool cmp(POINT p,POINT q)
    {
        return p.x<q.x;
    }
    
    double cal(double x,double y)
    {
        double tmp=0;
        for(int i=1;i<n;++i)
        {
            if(!l[i].exit) continue;
            tmp=fmax(tmp,l[i].k*x+l[i].b-y);
        }
        return tmp;
    }
    
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;++i) scanf("%lf",&e[i].x);
        for(int i=1;i<=n;++i) scanf("%lf",&e[i].y);
        sort(e+1,e+n+1,cmp);
        for(int i=1;i<n;++i)
        {
            if(fabs(e[i].x-e[i+1].x)<eps) continue;
            l[i].k=(e[i].y-e[i+1].y)/(e[i].x-e[i+1].x);
            l[i].b=e[i].y-e[i].x*l[i].k;
            l[i].exit=true;
        }
        double L,R,mid1,mid2;
        int T;
        double ans=1e20;
        for(int i=1;i<n;++i)
        {
            if(!l[i].exit) continue;
            T=100; L=e[i].x; R=e[i+1].x;
            while(T--)
            {
                mid1=L+(R-L)/3; mid2=R-(R-L)/3;
                if(cal(mid1,l[i].k*mid1+l[i].b)<cal(mid2,l[i].k*mid2+l[i].b)) R=mid2;
                else L=mid1;
            }
            ans=fmin(ans,cal(mid1,l[i].k*mid1+l[i].b));
        }
        printf("%.3lf",ans);
    }

    1038: [ZJOI2008]瞭望塔

    Time Limit: 10 Sec  Memory Limit: 162 MB
    Submit: 2658  Solved: 1084
    [Submit][Status][Discuss]

    Description

      致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安。我们
    将H村抽象为一维的轮廓。如下图所示 我们可以用一条山的上方轮廓折线(x1, y1), (x2, y2), …. (xn, yn)来描
    述H村的形状,这里x1 < x2 < …< xn。瞭望塔可以建造在[x1, xn]间的任意位置, 但必须满足从瞭望塔的顶端可
    以看到H村的任意位置。可见在不同的位置建造瞭望塔,所需要建造的高度是不同的。为了节省开支,dadzhi村长
    希望建造的塔高度尽可能小。请你写一个程序,帮助dadzhi村长计算塔的最小高度。

    Input

      第一行包含一个整数n,表示轮廓折线的节点数目。接下来第一行n个整数, 为x1 ~ xn. 第三行n个整数,为y1
     ~ yn。

    Output

      仅包含一个实数,为塔的最小高度,精确到小数点后三位。

    Sample Input

    【输入样例一】
    6
    1 2 4 5 6 7
    1 2 2 4 2 1
    【输入样例二】
    4
    10 20 49 59
    0 10 10 0

    Sample Output

    【输出样例一】
    1.000
    【输出样例二】
    14.500

    HINT

     N ≤ 300,输入坐标绝对值不超过106,注意考虑实数误差带来的问题。

  • 相关阅读:
    JAVA基础知识-java文化基础和运行环境
    一个获得jdbc方式Connection的静态方法
    Hibernate学习笔记(二)
    JVM学习笔记
    chrome常用插件
    面向站长和网站管理员的Web缓存加速指南
    OFBiz进阶之环境搭建(eclipse)
    OFBiz之SVN下载地址
    OFBiz进阶之HelloWorld(一)创建热部署模块
    Sublime Text 3插件之SublimeTmpl:新建文件的模版插件
  • 原文地址:https://www.cnblogs.com/TheRoadToTheGold/p/7923005.html
Copyright © 2011-2022 走看看