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

解题方法: 我们在纸上画一画发现,这个点要想看到所有的山顶,肯定是要在相邻两个山顶连线的半平面交中。那么显然这个相对高度最小的点肯定是在半平面交的边界上,因此有如下两种情况:
1、这个点在半平面交边界上两个直线的交点处。
2、这个点在某个山顶在半平面交的边界的投影处。
求解出半平面交后分别处理这种情况的答案,取最小值,第一次写半平面交,模板抄了hzwer的。

代码如下:

//bzoj 1038 HalfplaneIntersection
//zxy
#include <bits/stdc++.h>
using namespace std;
double ans = 1e10;
int n, cnt, tot;
struct Point{double x, y;Point(){}Point(double x, double y) : x(x), y(y){}
}p[1005], a[1005]; //input && Intersection of Half Plane
struct L{Point a, b;double slope;
}l[1005], q[1005];
Point operator-(Point u, Point v){return Point(u.x - v.x, u.y - v.y);
}
double operator *(Point u, Point v){return (u.x*v.y - u.y*v.x);
}
inline bool operator <(L a, L b){if(a.slope != b.slope) return a.slope < b.slope;else return (a.b - a.a) * (b.b - a.a) > 0;
}
Point inter(L a, L b){ //直线求交点,定比交点double k1, k2, t;k1 = (b.b - a.a) * (a.b - a.a);k2 = (a.b - a.a) * (b.a - a.a);t = k1 / (k1 + k2);Point ans;ans.x = b.b.x + (b.a.x - b.b.x) * t;ans.y = b.b.y + (b.a.y - b.b.y) * t;return ans;
}
bool jud(L a, L b, L t){ //判断当前直线在之前直线的左边Point p = inter(a, b);return (t.b - t.a) * (p - t.a) < 0;
}
void hpi(){ //半平面交int L = 1, R = 0;tot = 0;for(int i = 1; i <= cnt; i++){if(l[i].slope != l[i-1].slope) tot++;l[tot] = l[i];}cnt = tot;q[++R] = l[1]; q[++R] = l[2];for(int i = 3; i <= cnt; i++){while(L < R && jud(q[R-1], q[R], l[i])) R--;while(L < R && jud(q[L+1], q[L], l[i])) L++;q[++R] = l[i];}while(L < R && jud(q[R-1], q[R], q[L])) R--;while(L < R && jud(q[L+1], q[L], q[R])) L++;tot = 0;for(int i = L; i < R; i++) a[++tot] = inter(q[i], q[i+1]);
}
void pre_init(){ //预处理p[0].x = p[1].x, p[0].y = 100001;p[n+1].x = p[n].x, p[n+1].y = 100001; //加矩形框for(int i = 1; i <= n; i++){l[++cnt].a = p[i-1], l[cnt].b = p[i];l[++cnt].a = p[i], l[cnt].b = p[i+1];}for(int i = 1; i <= cnt; i++){l[i].slope = atan2(l[i].b.y - l[i].a.y, l[i].b.x - l[i].a.x);}sort(l + 1, l + cnt + 1);
}
void work(){for(int k = 1; k <= tot; k++){ //半平面交的交点上的答案for(int i = 1; i < n; i++){Point t; t.x = a[k].x; t.y = -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);}}}for(int k = 1; k <= n; k++){ //在平面上的点for(int i = 1; i < tot; i++){Point t; t.x = p[k].x; t.y = -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(){scanf("%d", &n);for(int i = 1; i <= n; i++) scanf("%lf", &p[i].x);for(int i = 1; i <= n; i++) scanf("%lf", &p[i].y);pre_init();hpi();work();printf("%.3f\n", ans);return 0;
}

BZOJ 1038: [ZJOI2008]瞭望塔 半平面交相关推荐

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

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

  2. ZJOI2008 瞭望塔 半平面交

    题意:给出一个以n个点为轮廓的村庄,在村庄任意位置放一个瞭望塔,使瞭望塔能看到村庄的所有位置,求瞭望塔最低高度. 只我们发现只有这个点在每个直线所在半平面以上的时候才能看到,如样例图: 还注意到,只有 ...

  3. bzoj 1038 [ZJOI2008]瞭望塔

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

  4. HYSBZ/BZOJ 1038 [ZJOI2008] 瞭望塔 - 计算几何

    题目描述 分析: 题目中说的"可以看见"means 在折线的每段所在直线朝x轴正方向,直线的左边一片区域(其实就是折线的每段所在直线的上面) 所以我们要求的就是此题折线所在直线相交 ...

  5. BZOJ 1038: [ZJOI2008]瞭望塔

    半平面交后,可能成为答案的点就是凸包上的点 和 山峰(分段函数的分段点). 枚举一下就行了. #include <bits/stdc++.h> using namespace std; c ...

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

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

  7. 【BZOJ 1038】 [ZJOI2008]瞭望塔

    1038: [ZJOI2008]瞭望塔 Time Limit: 10 Sec   Memory Limit: 162 MB Submit: 973   Solved: 428 [ Submit][ S ...

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

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

  9. bzoj 3190 赛车 半平面交

    直接写的裸的半平面交,已经有点背不过模板了... 这题卡精度,要用long double ,esp设1e-20... #include<iostream> #include<cstd ...

最新文章

  1. 一个c语言构造函数调用的问题(有趣)
  2. wordpress3.0.1安装出错的解决
  3. 项目案例分享二:密码策略与上次交互式登录
  4. listbox icon
  5. [译] Subject 和 Observable + Observer 的混淆指北[ Android RxJava2 ] ( 这什么鬼系列 ) 第八话...
  6. Trick(十六)—— 随机数的生成
  7. python地理数据处理相关的操作
  8. gcc/g++ 静态动态库 混链接.
  9. mysql8019zip安装_Eclipse+java+mysql8019实现数据库连接
  10. Python项目部署到Docker的完整过程
  11. BP神经网络做数据预测
  12. CDR 制作“决战高考”海报
  13. html手机保存图片不显示,手机保存的图片在相册显示不了解决方法
  14. 【带机器人】在线客服系统多商户客服源码 im即时通讯聊天 带注册 自适应网页 自动回复客服
  15. 大数据薪水大概多少_大数据工资一般多少
  16. Walkthrough: Word 2007 XML 格式
  17. 土微数字隔离器和接口类芯片可完美替代进口品牌TI和ADI
  18. 深度图转激光原理以及代码解析
  19. 【钉钉】钉钉疫情下扛起两亿上班族和全国中小学生!
  20. Adobe Photoshop CS4插件开发SDK的使用

热门文章

  1. 运维小知识之CDN内容分发网络原理解析
  2. JAVAScript实现人民币大小写转换算法
  3. ArcGIS教程:面积制表
  4. 【知识点】增量式编码器的工作原理和使用方法
  5. 全氟己基碘烷行业研究及十四五规划分析报告
  6. 南农计算机复试英语笔试,考研复试经验分享:英语+专业课+综合面试
  7. 从Firefox升级说学习方法
  8. ETL数据抽取---Apache Hop
  9. metaboxs.php,php – WooCommerce:将自定义Metabox添加到管理员订单页面
  10. 提高生产力之高效使用搜索引擎