1038: [ZJOI2008]瞭望塔

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 1628  Solved: 709
[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,注意考虑实数误差带来的问题。

首先有一个结论:分段一次函数的最值只有可能在边界和拐点处取到。(显然…)

所以我们可以先求出半平面交,然后枚举所有拐点和边界点,计算最小值。

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define F(i,j,n) for(int i=j;i<=n;i++)
#define D(i,j,n) for(int i=j;i>=n;i--)
#define ll long long
#define maxn 1005
#define eps 1e-8
#define inf 1000000000
using namespace std;
int n,cnt,tot;
double ans=1e60;
struct P{double x,y;}p[maxn],a[maxn];
struct L{P a,b;double angle;}l[maxn],q[maxn];
inline int read()
{int x=0,f=1;char ch=getchar();while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}while (ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}return x*f;
}
inline P operator -(P a,P b){return (P){a.x-b.x,a.y-b.y};}
inline double operator *(P a,P b){return a.x*b.y-a.y*b.x;}
inline bool operator <(L a,L b)
{if (fabs(a.angle-b.angle)<eps) return (a.b-a.a)*(b.b-a.a)>0;else return a.angle<b.angle;
}
inline P inter(L l1,L l2)
{double k1=(l2.b-l1.a)*(l1.b-l1.a),k2=(l1.b-l1.a)*(l2.a-l1.a),t=k1/(k1+k2);return (P){l2.b.x+(l2.a.x-l2.b.x)*t,l2.b.y+(l2.a.y-l2.b.y)*t};
}
inline bool judge(L l1,L l2,L t)
{P p=inter(l1,l2);return (t.b-t.a)*(p-t.a)<0;
}
inline void pre()
{p[0].x=p[1].x;p[0].y=inf;p[n+1].x=p[n].x;p[n+1].y=inf;F(i,0,n) l[++cnt]=(L){p[i],p[i+1]};F(i,1,cnt) l[i].angle=atan2(l[i].b.y-l[i].a.y,l[i].b.x-l[i].a.x);sort(l+1,l+cnt+1);
}
inline void hpi()
{int top=0,bot=1;tot=1;F(i,2,cnt){if (fabs(l[i].angle-l[i-1].angle)>=eps) tot++;l[tot]=l[i];}cnt=tot;q[++top]=l[1];q[++top]=l[2];F(i,3,cnt){while (bot<top&&judge(q[top-1],q[top],l[i])) top--;while (bot<top&&judge(q[bot+1],q[bot],l[i])) bot++;q[++top]=l[i];}while (bot<top&&judge(q[top-1],q[top],q[bot])) top--;while (bot<top&&judge(q[bot+1],q[bot],q[top])) bot++;tot=0;F(i,bot,top-1) a[++tot]=inter(q[i],q[i+1]);
}
inline void getans()
{F(k,1,tot) F(i,1,n-1){P t=(P){a[k].x,-1};if (a[k].x>=p[i].x&&a[k].x<=p[i+1].x)ans=min(ans,a[k].y-inter((L){p[i],p[i+1]},(L){t,a[k]}).y);}F(k,1,n) F(i,1,tot-1){P t=(P){p[k].x,-1};if (p[k].x>=a[i].x&&p[k].x<=a[i+1].x)ans=min(ans,inter((L){a[i],a[i+1]},(L){t,p[k]}).y-p[k].y);}
}
int main()
{n=read();F(i,1,n) p[i].x=read();F(i,1,n) p[i].y=read();pre();hpi();getans();printf("%.3lf\n",ans);return 0;
}

bzoj1038【ZJOI2008】瞭望塔相关推荐

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

    bzoj1038 [ZJOI2008]瞭望塔 原题地址:http://www.lydsy.com/JudgeOnline/problem.php?id=1038 题意: 村中要建立一个瞭望塔,我们将H ...

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

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

  3. bzoj1038 [ZJOI2008]瞭望塔

    Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们 将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1 ...

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

    题目: 我是超链接 题解: 很显然,只有瞭望塔和每个山顶形成直线的斜率的绝对值大于对应山坡的斜率,这个山坡才能看见.不难想到对所有的山坡求一个半平面交然后找到有山顶存在的部分,这个n<=300也 ...

  5. bzoj1038: [ZJOI2008]瞭望塔

    Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们 将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1 ...

  6. bzoj1038 [ZJOI2008]瞭望塔 枚举

    这个题实际上求的是半个凸包的核,但只需要枚举直线两两交点和地上的点就可以很快跑过 根据线性规划原理答案应该在直线交点上,为什么还要看地上的点? 因为实际上可行域是有下限的,有可能下限与地线重合 码(注 ...

  7. [BZOJ1038]ZJOI2008瞭望塔|半平面交

    考虑某个村庄可以被看见的区域,发现一条线段的上方就是可以看见端点的区域,那就把所有线段扔进去做半平面交,不要忘记了要加上两条左右边界..求出来之后发现答案要么是某个村庄往上到半平面交的一段距离,要么是 ...

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

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

  9. bzoj 1038 [ZJOI2008]瞭望塔

    1038: [ZJOI2008]瞭望塔 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 2438  Solved: 1004 [Submit][Sta ...

  10. luogu P2600 [ZJOI2008]瞭望塔

    luogu P2600 [ZJOI2008]瞭望塔 大意 题目讲得很清楚啊 题解 可以发现,那个点一定是某两条直线的交点 然后直接枚举两条直线就好了 // luogu-judger-enable-o2 ...

最新文章

  1. oracle emctl
  2. mysql 设置中文 重启_如何启动/停止/重启MySQL + 进入MYSQL-Go语言中文社区
  3. 软考网络工程师学习笔记1-计算机网络概念
  4. LeetCode 中级 - 第k个排列(60)
  5. 文件目录权限(chmod、chown、chgrp)umask、隐藏权限(lsattr、chattr)
  6. 验证码的旋转与放缩代码
  7. 网站开发流程以及HTML5简介(十)
  8. 川崎机器人仿真软件K-ROSET破解版的发展历程
  9. kpw3刷安卓教程2019_买kindle paperwhite4的别急,或许3更好用,因为3可以刷安卓!...
  10. 4K显示器在M1上打开HiDPI
  11. it黑马中学习的mybatis配置
  12. php 图片 变灰色,php[图片变灰]生成灰色图片代码
  13. Vue项目引入icon图标的两种方法
  14. CAD2018安装计算机黑屏,3dmax2018一打开就闪退的三种原因和解决方法
  15. WPF 控件 (二、按钮)
  16. ArcGIS中将一个shp图层批量分割成单个的shp;shp批量转geojson
  17. Linux 查看文件的内容 - head、tail、cat、more、less
  18. 全新的松松软文平台上线公告
  19. 专利评估的方法与流程!
  20. cad快速看图能合并图纸吗_CAD快速看图怎么对CAD图纸的版本进行转换?

热门文章

  1. Docker 镜像构建可以分享的快乐
  2. 程序员必备软件清单,没时间解释了,快上车
  3. 成功登陆港交所,顺丰同城的“跑腿”生意好做吗?
  4. web前端常用初始化css,开箱即用!!!
  5. 基础回顾(四)在mysql中的mul
  6. vue修改数组中的数据7个方法
  7. python mongodb驱动 pymongo模块常见用法总结
  8. 微信小程序之图片上传 demo
  9. 微信企业号通讯录导入
  10. 周末读书|《大众天文学》:少年,追星吗?