zoukankan      html  css  js  c++  java
  • BZOJ 1038 瞭望塔

    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

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

    Source

    半平面交。对于每条线段,所能看到其整条线段的点一定的在其所延长直线的上方,因此我们可以对所以直线求一次半平面交。

    然后,最优解一定在线段端点处或半平面交所得多边形的顶点处。

      1 #include<iostream>
      2 #include<algorithm>
      3 #include<cmath>
      4 #include<cstdio>
      5 #include<cstdlib>
      6 #include<cstring>
      7 using namespace std;
      8 
      9 #define eps (1e-6)
     10 #define oo ((double)(1ll<<50))
     11 #define maxn 310
     12 int n,m,tot,cnt;
     13 double ans = oo;
     14 struct NODE
     15 {
     16     double x,y;
     17     friend inline NODE operator + (const NODE &p,const NODE &q) { return (NODE) {p.x+q.x,p.y+q.y}; }
     18     friend inline NODE operator - (const NODE &p,const NODE &q) { return (NODE) {p.x-q.x,p.y-q.y}; }
     19     friend inline NODE operator * (const NODE &p,const double &q) { return (NODE) {p.x*q,p.y*q}; }
     20     friend inline double operator /(const NODE &p,const NODE &q) { return p.x*q.y-p.y*q.x; }
     21     inline double alpha() { return atan2(y,x); }
     22 }mou[maxn],pol[maxn],pp[maxn];
     23 struct LINE
     24 {
     25     NODE p,v; double slop;
     26     inline void maintain() { slop = v.alpha(); }
     27     friend inline bool operator <(const LINE &l1,const LINE &l2) { return l1.slop < l2.slop; }
     28 }lines[maxn],qq[maxn];
     29 struct SCAN
     30 {
     31     double x,y; int id; bool sign;
     32     friend inline bool operator <(const SCAN &a,const SCAN &b)
     33     {
     34         if (a.x != b.x) return a.x < b.x;
     35         else return a.sign < b.sign;
     36     }
     37 }bac[maxn];
     38 
     39 inline bool ol(const LINE &l,const NODE &p) { return l.v/(p-l.p) > 0; }
     40 
     41 inline NODE cp(const LINE &a,const LINE &b)
     42 {
     43     NODE u = a.p - b.p;
     44     double t = (b.v/u)/(a.v/b.v);
     45     return a.p+a.v*t;
     46 }
     47 
     48 inline bool para(const LINE &a,const LINE &b)
     49 {
     50     return fabs(a.v/b.v) < eps;
     51 }
     52 
     53 inline void ready()
     54 {
     55     for (int i = 1;i < n;++i)
     56     {
     57         lines[++tot] = (LINE) {mou[i],(mou[i+1]-mou[i])*1e-3};
     58         lines[tot].maintain();
     59     }
     60     lines[++tot] = (LINE) {(NODE) {-oo,0},(NODE){0,-0.001}};
     61     lines[tot].maintain();
     62     
     63     lines[++tot] = (LINE) {(NODE) {0,oo},(NODE){-0.001,0}};
     64     lines[tot].maintain();
     65     
     66     lines[++tot] = (LINE) {(NODE) {oo,0},(NODE){0,0.001}};
     67     lines[tot].maintain();
     68     
     69     lines[++tot] = (LINE) {(NODE) {0,-oo},(NODE){0.001,0}};
     70     lines[tot].maintain();
     71 }
     72 
     73 inline int half_plane_intersection()
     74 {
     75     sort(lines+1,lines+tot+1);
     76     int head,tail;
     77     qq[head = tail = 1] = lines[1];
     78     for (int i = 2;i <= tot;++i)
     79     {
     80         while (head < tail&&!ol(lines[i],pp[tail-1])) --tail;
     81         while (head < tail&&!ol(lines[i],pp[head])) ++head;
     82         qq[++tail] = lines[i];
     83         if (para(qq[tail],qq[tail-1]))
     84         {
     85             tail--;
     86             if (ol(qq[tail],lines[i].p)) qq[tail] = lines[i];
     87         }
     88         if (head < tail) pp[tail-1] = cp(qq[tail],qq[tail-1]);
     89     }
     90     while (head < tail && !ol(qq[head],pp[tail-1])) --tail;
     91     if (tail-head <= 0) return 0;
     92     pp[tail] = cp(qq[tail],qq[head]);
     93     for (int i = head;i <= tail;++i) pol[++m] = pp[i];
     94     pol[0] = pol[m];
     95     return m;
     96 }
     97 
     98 inline void work()
     99 {
    100     int all = 0;
    101     for (int i = 1;i <= n;++i)
    102         bac[++all] = (SCAN) { mou[i].x,mou[i].y,i,false };
    103     for (int i = 1;i <= m;++i)
    104         if (pol[i].x >= mou[1].x&&pol[i].x <= mou[n].x)
    105             bac[++all] = (SCAN) { pol[i].x,pol[i].y,i,true };
    106     sort(bac+1,bac+all+1);
    107     int s1,s2;
    108     for (int i = 1;i <= all;++i) if (bac[i].sign) { s1 = bac[i].id-1; break; }
    109     for (int i = 1;i <= all;++i)
    110     {
    111         LINE l = (LINE) {(NODE) {bac[i].x,0},(NODE) {0,1}},l1; NODE p;
    112         if (!bac[i].sign)
    113         {
    114             l1= (LINE) {pol[s1],pol[s1+1]-pol[s1]};
    115             s2 = bac[i].id;
    116         }
    117         else
    118         {
    119             l1= (LINE) {mou[s2],mou[s2+1]-mou[s2]};
    120             s1 = bac[i].id;
    121         }
    122         p = cp(l,l1);
    123         ans = min(ans,fabs(p.y-bac[i].y));    
    124     }
    125  }
    126 
    127 int main()
    128 {
    129     freopen("1038.in","r",stdin);
    130     freopen("1038.out","w",stdout);
    131     scanf("%d ",&n);
    132     for (int i = 1;i <= n;++i) scanf("%lf",&mou[i].x);
    133     for (int i = 1;i <= n;++i) scanf("%lf",&mou[i].y);
    134     ready();
    135     half_plane_intersection();
    136     work();
    137     printf("%.3lf",ans);
    138     fclose(stdin); fclose(stdout);
    139     return 0;
    140 }
    View Code
  • 相关阅读:
    脚本添加crontab任务
    docker mysql8 注意
    使用 logrotate 清理日志
    腾讯云cos对象在线显示
    快速部署私人git服务--基于docker化Gogs
    grep 使用
    vsftpd 新增虚拟用户
    unistd.h
    ffmpeg
    H264视频压缩算法
  • 原文地址:https://www.cnblogs.com/mmlz/p/4276082.html
Copyright © 2011-2022 走看看