题目链接

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. Cypress USB3014 controlEndPoint 使用事项

    control endpoint 发送,接收数据 返回fasle , lastError = 997, 抓包查看 Control Transfer (UP) XXXXXXXXX 1. Device: ...

  2. angular之增删改查

    <!DOCTYPE html> <html lang="en" ng-app="app"> <head> <meta ...

  3. javascript——对象的概念——函数 2 (内建函数与类型转换)

    javascript 有许多内建函数,用于各种操作,以下为常用的内建方法. 1.parseInt(object,int):将输入的 int 进制的值 object 转换为 10 进制的数值: obje ...

  4. python爬虫框架(2)--PySpider框架安装配置

    1.安装 1.phantomjs PhantomJS 是一个基于 WebKit 的服务器端 JavaScript API.它全面支持web而不需浏览器支持,其快速.原生支持各种Web标准:DOM 处理 ...

  5. android下db-journal文件作用

    在学习数据库sqlite的过程中,发现在源文件包里除了生成db类型的数据库文件,还生成了db-journal类型的同名文件 查询网上资料后知道该文件是sqlite的一个临时的日志文件,主要用于sqli ...

  6. day70-oracle 12-Java调用存储过程和存储函数

    我们现在调用的是存储过程和存储函数.用CallableSatement调用存储函数和存储过程. RDBMS:关系数据库.使用标准方式调用存储过程.也就是说:在mysql中调用和在oracle中调用的写 ...

  7. elasticsearch2.x ik插件

    先来一个标准分词(standard),配置如下: curl -XPUT localhost:/local -d '{ "settings" : { "analysis&q ...

  8. dedecms出错此问题:Cannot_modify_header_information_-_headers_already_sent_by_(output_started_at

    修改php.ini文件,php.ini配置问题,解决办法:打开 php.ini 然后把 output_buffering 设为 on ,重启iis或apache即可. 出现以上问题可能是由于更换空间, ...

  9. JavaScript toLowerCase() 方法

    定义和用法 toLowerCase() 方法用于把字符串转换为小写. 语法 stringObject.toLowerCase() 返回值 一个新的字符串,在其中 stringObject 的所有大写字 ...

  10. webfrom 做项目的注意事项

    1.展示细节 如男女显示问题 不能显示true   false  时间转换成中文  民族显示汉字  不能直接显示代码2.用户名重复验证 从数据库中查询验证4.日期判断 判断年份有点问题   var y ...