题目链接

BZOJ/洛谷

题目描述

致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安。

我们将H村抽象为一维的轮廓。如下图所示:

我们可以用一条山的上方轮廓折线\((x_1,y_1),(x_2,y_2)…(x_n,y_n)\)来描述H村的形状,这里\(x_1 < x_2 < …< x_n\)。瞭望塔可以建造在\([x_1,x_n]\)间的任意位置,但必须满足从瞭望塔的顶端可以看到H村的任意位置。可见在不同的位置建造瞭望塔,所需要建造的高度是不同的。为了节省开支,dadzhi村长希望建造的塔高度尽可能小。

请你写一个程序,帮助dadzhi村长计算塔的最小高度。

输入

第一行包含一个整数\(n\),表示轮廓折线的节点数目。接下来第一行\(n\)个整数, 为\(x_1\sim x_n\). 第三行n个整数,为\(y_1\sim y_n\)。

输出

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

样例

样例输入

6
1 2 4 5 6 7
1 2 2 4 2 1

样例输出

1.000

数据范围

对于\(60\%\)的数据,\(N\leq60\)。

对于\(100\%\)的数据,\(N\leq300\),输入坐标绝对值不超过\(10^6\),注意考虑实数误差带来的问题。

题解

半平面交好题(其实可以暴枚)。

首先,假设瞭望塔顶为点\(P\),那么\(P\)必定在轮廓线上每条边往上的半平面的交集里面。

因此先做一遍半平面交,由于必定是无界的,我在左右和上侧各加了一个半平面(做完之后把不需要的边界去掉)。

这样我们就得到了一个下凸壳,如果瞭望塔建在\(x_0\)这个位置,那么必定是建到直线\(x=x_0\)与这个凸壳的交点的高度即可。然后考虑到高度是由上下共同决定的,经过显而易见的贪心,可以发现瞭望塔的横坐标要么是这个凸壳上的顶点,要么是下方轮廓线的端点,\(O(n)\)扫一遍即可。总复杂度\(O(n\log n)\)。

坑:答案可能很大,所以\(ans\)初始值得设得很大。

\(Code:\)

#include <cmath>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define N 100005
#define eps 1e-8
int n, m, h, t, cnt;
bool More(double a, double b){return a > b + eps;}
bool Less(double a, double b){return a < b - eps;}
bool Emore(double a, double b){return a > b - eps;}
bool Eless(double a, double b){return a < b + eps;}
bool Equal(double a, double b){return fabs(a - b) < eps;}
struct Point
{
double x, y;
Point(){}
Point(double a, double b){x = a, y = b;}
Point operator + (Point b){return Point(x + b.x, y + b.y);}
Point operator - (Point b){return Point(x - b.x, y - b.y);}
Point operator * (double c){return Point(x * c, y * c);}
Point operator / (double c){return Point(x / c, y / c);}
}A[N], B[N], p[N];
struct Line//直线、线段、射线s->t,向量为t-s
{
Point s, t;
Line(){};
Line(Point a, Point b){s = a, t = b;}
}S[N], q[N];
double Cross(Point a, Point b){return a.x * b.y - a.y * b.x;}
double Length(Point a){return sqrt(a.x * a.x + a.y * a.y);}
bool Onright(Line s, Point p){return More(Cross(p - s.s, s.t - s.s), 0);}
Point Intersect(Line a, Line b)
{
double s1 = Cross(a.t - a.s, b.s - a.s);
double s2 = Cross(b.t - a.t, a.t - a.s);
return b.s + (b.t - b.s) / (s1 + s2) * s1;
}
double Angle(Point p){return atan2(p.y, p.x);}
int cmp(Line s1, Line s2)//象限角度数越低的越靠前(-180,180]
{
Point a = s1.t - s1.s;
Point b = s2.t - s2.s;
if (!Equal(Angle(a), Angle(b)))return Angle(a) < Angle(b);
return Onright(s1, s2.s);
}
int cmp2(Point p1, Point p2){return p1.x < p2.x;}
int main()
{
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%lf", &A[i].x);
for (int i = 1; i <= n; i++)
scanf("%lf", &A[i].y);
for (int i = 1; i < n; i++)
S[++cnt] = Line(A[i], A[i + 1]);
S[++cnt] = Line(Point(A[1].x, 1e+12), Point(A[1].x, A[1].y));
S[++cnt] = Line(Point(A[n].x, 1e+12), Point(A[1].x, 1e+12));
S[++cnt] = Line(Point(A[n].x, A[n].y), Point(A[n].x, 1e+12));
sort(S + 1, S + cnt + 1, cmp);
int w = 1;
for (int i = 2; i <= cnt; i++)
if (!Equal(Angle(S[i].t - S[i].s), Angle(S[i - 1].t - S[i - 1].s)))
S[++w] = S[i];
cnt = w;
h = 1, t = 0;
q[++t] = S[1];
for (int i = 2; i <= cnt; i++)
{
while (h < t && Onright(S[i], p[t - 1]))t--;
while (h < t && Onright(S[i], p[h]))h++;
q[++t] = S[i];
if (h < t)
p[t - 1] = Intersect(q[t], q[t - 1]);
}
while (h < t && Onright(q[h], p[t - 1]))t--;
if (h < t)p[t] = Intersect(q[t], q[h]);
cnt = 0;
for (int i = h; i <= t; i++)
B[++cnt] = p[i];
sort(B + 1, B + cnt + 1, cmp2);
w = 1;
for (int i = 2; i <= cnt; i++)
if (Less(B[i].y, 1e+11))
B[++w] = B[i];
cnt = w;
double ans = 1e+10;
int w1 = 1, w2 = 2;
A[0].x = A[1].x - 1;
B[0].x = B[1].x - 1;
while (w1 <= cnt || w2 <= n)
{
if (w2 > n || (w1 <= cnt && B[w1].x < A[w2].x))
{
Point s = A[w2 - 1] + (A[w2] - A[w2 - 1]) / (A[w2].x - A[w2 - 1].x) * (B[w1].x - A[w2 - 1].x);
ans = min(ans, B[w1].y - s.y);
w1++;
}
else
{
Point s = B[w1 - 1] + (B[w1] - B[w1 - 1]) / (B[w1].x - B[w1 - 1].x) * (A[w2].x - B[w1 - 1].x);
ans = min(ans, s.y - A[w2].y);
w2++;
}
}
printf("%.3f\n", ans);
}

「BZOJ1038」「洛谷P2600」「ZJOI2008」瞭望塔 半平面交+贪心的更多相关文章

  1. 洛谷P4250 [SCOI2015]小凸想跑步(半平面交)

    题面 传送门 题解 设\(p\)点坐标为\(x_p,y_p\),那么根据叉积可以算出它与\((i,i+1)\)构成的三角形的面积 为了保证\(p\)与\((0,1)\)构成的面积最小,就相当于它比其它 ...

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

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

  3. 洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心)

    洛谷P1484 种树&洛谷P3620 [APIO/CTSC 2007]数据备份 题解(堆+贪心) 标签:题解 阅读体验:https://zybuluo.com/Junlier/note/132 ...

  4. 洛谷 P2587 BZOJ 1034 [ZJOI2008]泡泡堂

    题目描述 //不知道为什么BZOJ和洛谷都没有这幅图了,大牛们几年前的博客上都有这幅图的,把它贴上来吧 第XXXX届NOI期间,为了加强各省选手之间的交流,组委会决定组织一场省际电子竞技大赛,每一个省 ...

  5. 洛谷 P2279 [HNOI2003]消防局的设立 (树形dp or 贪心)

    一看到这道题就知道是树形dp 之前做过类似的题,只不过保护的范围是1 所以简单很多. 这道题保护的范围是2,就复杂了很多. 我就开始列状态,然后发现竟然有5种 然后我就开始列方程. 但是我考虑的时候是 ...

  6. 【洛谷】2607: [ZJOI2008]骑士【树形DP】【基环树】

    P2607 [ZJOI2008]骑士 题目描述 Z国的骑士团是一个很有势力的组织,帮会中汇聚了来自各地的精英.他们劫富济贫,惩恶扬善,受到社会各界的赞扬. 最近发生了一件可怕的事情,邪恶的Y国发动了一 ...

  7. 洛谷 P1478 陶陶摘苹果(升级版)【贪心/结构体排序/可用01背包待补】

    [链接]:https://www.luogu.org/problemnew/show/P1478 题目描述 又是一年秋季时,陶陶家的苹果树结了n个果子.陶陶又跑去摘苹果,这次她有一个a公分的椅子.当他 ...

  8. 洛谷P2114 起床困难综合症【位运算】【贪心】

    题目:https://www.luogu.org/problemnew/show/P2114 题意:有n个操作,每个可以是与.或.异或 一个数. 初始值是0~m之间的一个数,问经过n个运算之后,可以得 ...

  9. 洛谷 P2590 BZOJ 1036 [ZJOI2008]树的统计

    Time limit 10000 ms//另外,BZOJ只算所有点的总时限,所以可能会放过一些原本会TLE的代码 Memory limit 165888 kB OS Linux SourceZJOI2 ...

随机推荐

  1. react-router4.x 组件和api介绍

    react-router实用4.2.0 react-router非常复杂整体,比vue-router强大很多,好好研究,对你自身能力提高很有帮助 安装 cnpm install react-route ...

  2. 查看hdfs各目录分别占用多少空间

    之前在网上搜索到的全部单位好像都是byte的,看起来很麻烦,然后自己看了下 hadoop fs -help [hadoop@slave3 java]$ hadoop fs -help Usage: h ...

  3. 常见地图服务(WMS、WFS、WCS、TMS、WMTS

    1.网络地图服务(WMS) 网络地图服务(WMS)利用具有地理空间位置信息的数据制作地图.其中将地图定义为地理数据可视的表现.能够根据用户的请求返回相应的地图(包括PNG,GIF,JPEG等栅格形式或 ...

  4. Arduino Uno 在win7 64位下的驱动问题

    1.解压[mdmcpq.inf_amd64_neutral_fbc4a14a6a13d0c8.rar],将[mdmcpq.inf_amd64_neutral_fbc4a14a6a13d0c8]文件夹复 ...

  5. [codeforces126B]Password

    解题关键:KMP算法中NEXT数组的理解. #include<bits/stdc++.h> #define maxn 1000006 using namespace std; typede ...

  6. C++——override

    override关键字作用: 如果派生类在虚函数声明时使用了override描述符,那么该函数必须重载其基类中的同名函数,否则代码将无法通过编译.举例子说明 struct Base { virtual ...

  7. 一堵墙IFC数据-wall.ifc

    这是一面墙的IFC数据内容 =====================================文档内容======================================= ISO-1 ...

  8. Java之IO流学习总结

    流:可以理解为数据的流动,就是一个数据流,IO流最终要以对象来体现 流的分类:     按照流的方向:输入流和输出流  (输入流只能进行读操作,输出流只能进行写操作)     按照处理数据的不同:字节 ...

  9. 神奇的overflow:hidden及其背后的原理

    先来看两个overflow:hidden的使用例子 1.嵌套布局内部块元素设置float:left时,导致外部元素塌方,高度为0的问题. <div class="wrap"& ...

  10. svn冲突问题详解 SVN版本冲突解决详解

    svn冲突问题详解 SVN版本冲突解决详解 (摘自西西软件园,原文链接http://www.cr173.com/html/46224_1.html) 解决版本冲突的命令.在冲突解决之后,需要使用svn ...