传送门

题意:给出一个nnn个点的轮廓,要求找一个高度最小的点使得它能够看见所有拐点。


思路:之间建半平面交然后取半平面交上的每个交点和每个轮廓更新答案即可。

代码:

#include<bits/stdc++.h>
#define ri register int
using namespace std;
typedef long long ll;
const int N=305;
struct pot{
    double x,y;
    pot(double _x=0,double _y=0):x(_x),y(_y){}
    friend inline pot operator+(const pot&a,const pot&b){return pot(a.x+b.x,a.y+b.y);}
    friend inline pot operator-(const pot&a,const pot&b){return pot(a.x-b.x,a.y-b.y);}
    friend inline double operator^(const pot&a,const pot&b){return a.x*b.y-a.y*b.x;}
    friend inline pot operator*(const double&a,const pot&b){return pot(a*b.x,a*b.y);}
}a[N];
struct L{
    pot a,b;
    double ang;
    L(pot _a=pot(0,0),pot _b=pot(0,0),double _ang=0):a(_a),b(_b),ang(_ang){}
    friend inline bool operator<(const L&a,const L&b){return a.ang==b.ang?((b.b-a.a)^(b.b-b.a))>0:a.ang<b.ang;}
}l[N];
inline pot inter(const L&a,const L&b){
    double k1=(b.b-a.b)^(b.b-a.a),k2=(b.a-a.a)^(b.a-a.b),k=k2/(k1+k2);
    return b.a+k*(b.b-b.a);
}
int n,m;
inline bool check(const L&a,const L&b,const L&c){
    pot tmp=inter(c,b);
    return ((a.b-tmp)^(a.a-tmp))>0;
}
inline void hpi(L a[]){
    static int top;
    sort(l+1,l+n);
    m=0;
    for(ri i=1;i<n;++i)if(i==1||l[i].ang!=l[i-1].ang)l[++m]=l[i];
    top=2;
    for(ri i=3;i<=m;++i){
        while(top>1&&check(l[top-1],l[top],l[i]))--top;
        l[++top]=l[i];
    }
    m=top;
}
inline int read(){
    int ans=0;
    bool f=1;
    char ch=getchar();
    while(!isdigit(ch))f^=(ch=='-'),ch=getchar();
    while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
    return f?ans:-ans;
}
int main(){
    n=read();
    for(ri i=1;i<=n;++i)a[i].x=read();
    for(ri i=1;i<=n;++i)a[i].y=read();
    for(ri i=2;i<=n;++i)l[i-1]=L(a[i-1],a[i],atan2(a[i].y-a[i-1].y,a[i].x-a[i-1].x));
    hpi(l);
    double ans=1e18;
    for(ri i=1,j=1;i<=n;++i){
        while(j<m&&inter(l[j],l[j+1]).x<a[i].x)++j;
        pot tmp=inter(l[j],L(a[i],pot(a[i].x,-1),0.0));
        ans=min(ans,tmp.y-a[i].y);
    }
    for(ri i=1,j=1;i<m;++i){
        pot tmp=inter(l[i],l[i+1]),upd;
        if(tmp.x<a[1].x)continue;
        while(j<n&&a[j+1].x<tmp.x)++j;
        if(j==n)continue;
        upd=inter(L(a[j],a[j+1]),L(pot(tmp.x,-1),tmp));
        ans=min(ans,tmp.y-upd.y);
    }
    printf("%.3lf",ans);
    return 0;
}

2019.02.21 bzo1038: [ZJOI2008]瞭望塔(半平面交)的更多相关文章

  1. [BZOJ1038][ZJOI2008]瞭望塔(半平面交)

    1038: [ZJOI2008]瞭望塔 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2999  Solved: 1227[Submit][Statu ...

  2. 「BZOJ1038」「洛谷P2600」「ZJOI2008」瞭望塔 半平面交+贪心

    题目链接 BZOJ/洛谷 题目描述 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安. 我们将H村抽象为一维的轮廓.如下图所示: 我们可以用一条山的上方 ...

  3. bzoj 1038 瞭望塔 半平面交+分段函数

    题目大意 给你一座山,山的形状在二维平面上为折线 给出\((x_1,y_1),(x_2,y_2)...(x_n,y_n)\)表示山的边界点或转折点 现在要在\([x_1,x_n]\)(闭区间)中选择一 ...

  4. 【BZOJ 1038】 1038: [ZJOI2008]瞭望塔

    1038: [ZJOI2008]瞭望塔 Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 ...

  5. 【BZOJ1038】[ZJOI2008]瞭望塔 半平面交

    [BZOJ1038][ZJOI2008]瞭望塔 Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如 ...

  6. bzoj千题计划126:bzoj1038: [ZJOI2008]瞭望塔

    http://www.lydsy.com/JudgeOnline/problem.php?id=1038 本题可以使用三分法 将点按横坐标排好序后 对于任意相邻两个点连成的线段,瞭望塔的高度 是单峰函 ...

  7. bzoj 1038 [ZJOI2008]瞭望塔(半平面交)

    [题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1038 [题意] 找一个最低塔高使可以看到村庄的每一个角落. [思路] 半平面交 能够看 ...

  8. [日常摸鱼]bzoj1038 [ZJOI2008]瞭望塔-模拟退火/几何

    题意:给一条平面内$n$个点的折线,要求在折线上搞一个高度$h$的瞭望塔,能够看见折线上所有的点,求$h$的最小值($n \leq 300$) updata2018.1.21 正解半平面交在另一篇里面 ...

  9. 1038: [ZJOI2008]瞭望塔

    半平面交. 半平面指的就是一条直线的左面(也不知道对不对) 半平面交就是指很多半平面的公共部分. 这道题的解一定在各条直线的半平面交中. 而且瞭望塔只可能在各个点或者半平面交折线的拐点处. 求出半平面 ...

随机推荐

  1. [UnityShader基础]05.模板测试

    参考链接: https://blog.csdn.net/u011047171/article/details/46928463 https://blog.csdn.net/JohnBlu/articl ...

  2. uva-10245-分治

    题意:数组二维空间内的点,求最近的俩个点的距离. 根据x排序,求左部分的最近距离,右部分最近距离,然后以中点,当前距离为半径,计算所有的点距离. #include <string> #in ...

  3. GIT BRANCHING

    GIT BRANCHING generalizations Let's take a moment to review the main concepts and commands from the ...

  4. Linux命令:logout

    logout [n] 退出当前shell,给父shell返回状态码n. 参考return.

  5. Linux常用基础操作命令大全(超实用精心整理)

    相信大家都对黑客那种只用命令行对电脑操作的风格惊呆了,其实你也可以做到.linux是一款不同于windows的操作系统,而且它是黑客.渗透人员.运维人员等等必会的.如果你想学习,小编下面整理的命令将会 ...

  6. 将font-size设置为 12px 以下,Chrome浏览器只能显示12px怎么办?

    将字体大小设置为12px以下,而Chrome浏览器依然只显示12px,因为 Chrome 这款任性的浏览器做了如下限制: 1. font-size 有一个最小值 12px(不同操作系统.不同语言可能限 ...

  7. MySQL中的sort_buffer_size参数大小的设置问题

    看到sort_buffer_size这个参数(connect级别的参数,MySQL5.7,默认值是1048576字节,也就是1MB)的默认值这么小,想着是不是可以调大一点,反正内存动不动几十个GB的, ...

  8. 算法题——给定一个数组 arr,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

    参考自:https://blog.csdn.net/qq_38200548/article/details/80688630 示例: 输入: [0,1,0,3,12] 输出: [1,3,12,0,0] ...

  9. container injection——容器技术

    (一)容器技术为什么出现 在很久很久以前,想要在线上服务器部署一个应用,首先需要购买一个物理服务器,在服务器安装一个操作系统,然后安装好应用所需要的各种依赖环境,最后才可以进行应用的部署,而且一台服务 ...

  10. 商品批量删除(mybatis中集合的使用)

    <!-- 根据主键批量删除 --> <delete id="deleteByKeys"> DELETE FROM product WHERE id in & ...