BZOJ 1038: [ZJOI2008]瞭望塔 半平面交
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]瞭望塔 半平面交相关推荐
- [BZOJ1038]ZJOI2008瞭望塔|半平面交
考虑某个村庄可以被看见的区域,发现一条线段的上方就是可以看见端点的区域,那就把所有线段扔进去做半平面交,不要忘记了要加上两条左右边界..求出来之后发现答案要么是某个村庄往上到半平面交的一段距离,要么是 ...
- ZJOI2008 瞭望塔 半平面交
题意:给出一个以n个点为轮廓的村庄,在村庄任意位置放一个瞭望塔,使瞭望塔能看到村庄的所有位置,求瞭望塔最低高度. 只我们发现只有这个点在每个直线所在半平面以上的时候才能看到,如样例图: 还注意到,只有 ...
- bzoj 1038 [ZJOI2008]瞭望塔
1038: [ZJOI2008]瞭望塔 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 2438 Solved: 1004 [Submit][Sta ...
- HYSBZ/BZOJ 1038 [ZJOI2008] 瞭望塔 - 计算几何
题目描述 分析: 题目中说的"可以看见"means 在折线的每段所在直线朝x轴正方向,直线的左边一片区域(其实就是折线的每段所在直线的上面) 所以我们要求的就是此题折线所在直线相交 ...
- BZOJ 1038: [ZJOI2008]瞭望塔
半平面交后,可能成为答案的点就是凸包上的点 和 山峰(分段函数的分段点). 枚举一下就行了. #include <bits/stdc++.h> using namespace std; c ...
- 【BZOJ 1038】 1038: [ZJOI2008]瞭望塔
1038: [ZJOI2008]瞭望塔 Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们 将H村抽象为一维的轮廓.如下图所 ...
- 【BZOJ 1038】 [ZJOI2008]瞭望塔
1038: [ZJOI2008]瞭望塔 Time Limit: 10 Sec Memory Limit: 162 MB Submit: 973 Solved: 428 [ Submit][ S ...
- bzoj千题计划126:bzoj1038: [ZJOI2008]瞭望塔
http://www.lydsy.com/JudgeOnline/problem.php?id=1038 本题可以使用三分法 将点按横坐标排好序后 对于任意相邻两个点连成的线段,瞭望塔的高度 是单峰函 ...
- bzoj 3190 赛车 半平面交
直接写的裸的半平面交,已经有点背不过模板了... 这题卡精度,要用long double ,esp设1e-20... #include<iostream> #include<cstd ...
最新文章
- 一个c语言构造函数调用的问题(有趣)
- wordpress3.0.1安装出错的解决
- 项目案例分享二:密码策略与上次交互式登录
- listbox icon
- [译] Subject 和 Observable + Observer 的混淆指北[ Android RxJava2 ] ( 这什么鬼系列 ) 第八话...
- Trick(十六)—— 随机数的生成
- python地理数据处理相关的操作
- gcc/g++ 静态动态库 混链接.
- mysql8019zip安装_Eclipse+java+mysql8019实现数据库连接
- Python项目部署到Docker的完整过程
- BP神经网络做数据预测
- CDR 制作“决战高考”海报
- html手机保存图片不显示,手机保存的图片在相册显示不了解决方法
- 【带机器人】在线客服系统多商户客服源码 im即时通讯聊天 带注册 自适应网页 自动回复客服
- 大数据薪水大概多少_大数据工资一般多少
- Walkthrough: Word 2007 XML 格式
- 土微数字隔离器和接口类芯片可完美替代进口品牌TI和ADI
- 深度图转激光原理以及代码解析
- 【钉钉】钉钉疫情下扛起两亿上班族和全国中小学生!
- Adobe Photoshop CS4插件开发SDK的使用