【BZOJ 1038】【ZJOI 2008】瞭望塔
http://www.lydsy.com/JudgeOnline/problem.php?id=1038
半平面交裸题,求完半平面后在折线段上的每个点竖直向上和半平面上的每个点竖直向下求距离,统计最小的值作为答案即可。
1A!!!斯巴达!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#include<cmath>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 303; struct Point {
double x, y;
Point(double _x = 0, double _y = 0) : x(_x), y(_y) {}
} t[N], p[N];
struct Line {
Point p, v; double ang;
Line(Point _p = Point(0, 0), Point _v = Point(0, 0), double _ang = 0) : p(_p), v(_v), ang(_ang) {}
bool operator < (const Line &x) const {
return ang < x.ang;
}
} l[N], q[N]; Point operator + (Point a, Point b) {return Point(a.x + b.x, a.y + b.y);}
Point operator - (Point a, Point b) {return Point(a.x - b.x, a.y - b.y);}
Point operator * (Point a, double x) {return Point(a.x * x, a.y * x);}
Point operator / (Point a, double x) {return Point(a.x / x, a.y / x);} int dcmp(double x) {return fabs(x) < 1e-8 ? 0 : (x < 0 ? -1 : 1);}
double Dot(Point a, Point b) {return a.x * b.x + a.y * b.y;}
double Cross(Point a, Point b) {return a.x * b.y - a.y * b.x;}
double sqr(double x) {return x * x;}
double dis(Point a, Point b) {return sqrt(sqr(a.x - b.x) + sqr(a.y - b.y));} bool onleft(Point a, Line b) {return dcmp(Cross(a - b.p, b.v)) < 0;}
Point intersection(Line a, Line b) {
Point u; double t;
u = a.p - b.p;
t = Cross(b.v, u) / Cross(a.v, b.v);
return a.p + (a.v * t);
} int n, head = 1, tail = 2;
double ans; void mkhalf() {
q[1] = l[1]; q[2] = l[2];
p[1] = intersection(q[1], q[2]);
for(int i = 3; i < n; ++i) {
while (head < tail && !onleft(p[tail - 1], l[i])) --tail;
while (head < tail && !onleft(p[head], l[i])) ++head;
q[++tail] = l[i];
if (dcmp(Cross(q[tail].v, q[tail - 1].v) == 0)) {
--tail;
if (onleft(l[i].p, q[tail])) q[tail] = l[i];
}
if (head < tail) p[tail - 1] = intersection(q[tail - 1], q[tail]);
}
// while (head < tail + 1 && !onleft(p[tail - 1], q[head])) --tail;
} double cal(int num) {
Point j;
double x = t[num].x, y = t[num].y;
if (x <= p[head].x) {
j = intersection(q[head], Line(t[num], Point(0, 1)));
return j.y - y;
}
if (x >= p[tail - 1].x) {
j = intersection(q[tail], Line(t[num], Point(0, 1)));
return j.y - y;
}
int left = head, right = tail - 1, mid;
while (left < right) {
mid = (left + right + 1) >> 1;
if (p[mid].x > x) right = mid - 1;
else left = mid;
}
j = intersection(q[left + 1], Line(t[num], Point(0, 1)));
return j.y - y;
} double cal2(int num) {
Point j;
double x = p[num].x, y = p[num].y;
int left = 1, right = n, mid;
while (left < right) {
mid = (left + right + 1) >> 1;
if (t[mid].x > x) right = mid - 1;
else left = mid;
}
j = intersection(Line(t[left], t[left + 1] - t[left]), Line(p[num], Point(0, -1)));
return y - j.y;
} int main() {
scanf("%d", &n);
for(int i = 1; i <= n; ++i) scanf("%lf", &t[i].x);
for(int i = 1; i <= n; ++i) scanf("%lf", &t[i].y); for(int i = 1; i < n; ++i) l[i] = Line(t[i], t[i + 1] - t[i]), l[i].ang = atan2(l[i].v.y, l[i].v.x);
sort(l + 1, l + n);
mkhalf(); ans = cal(1);
for(int i = 2; i <= n; ++i)
ans = min(ans, cal(i));
for(int i = head; i < tail; ++i)
if (t[1].x <= p[i].x && p[i].x <= t[n].x)
ans = min(ans, cal2(i)); // for(int i = head; i < tail; ++i) printf("%.2lf %.2lf\n", p[i].x, p[i].y); printf("%.3lf\n", ans + 1e-8);
return 0;
}
因为半平面不会围成一个"圈",所以我把最后"去除冗余"的部分注释掉了。最后输出答案加eps是听别人说的,不加会怎么样呢,我也不知道_(:з」∠)_
【BZOJ 1038】【ZJOI 2008】瞭望塔的更多相关文章
- 【BZOJ 1038】[ZJOI2008]瞭望塔
[题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1038 [题意] [题解] 可以看到所有村子的瞭望塔所在的位置只会是在相邻两个村子所代表 ...
- BZOJ 1040 ZJOI 2008 骑士 基环树林+树形DP
题目大意:有一些骑士.他们每个人都有一个权值.可是因为一些问题,每个骑士都特别讨厌还有一个骑士.所以不能把他们安排在一起.求这些骑士所组成的编队的最大权值和是多少. 思路:首先貌似是有向图的样子,可是 ...
- BZOJ 1040 ZJOI 2008 骑士 树形DP
题意: 有一些战士,他们有战斗力和讨厌的人,选择一些战士,使他们互不讨厌,且战斗力最大,范围1e6 分析: 把战士看作点,讨厌的关系看作一条边,连出来的是一个基环树森林. 对于一棵基环树,我们找出环, ...
- bzoj 1034 [ ZJOI 2008 ] 泡泡堂BNB —— 贪心
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1034 一开始想了个很麻烦的贪心做法,对于每个 a[i],找第一个大于它的 b 匹配…… 然后 ...
- 【BZOJ】【1038】【ZJOI2008】瞭望塔
计算几何/半平面交 说是半平面交,实际上只是维护了个下凸壳而已……同1007水平可见直线 对于每条线段,能看到这条线段的点都在这条线段的“上方”,那么对所有n-1条线段求一个可视区域的交,就是求一个半 ...
- 【BZOJ 1038】 1038: [ZJOI2008]瞭望塔
1038: [ZJOI2008]瞭望塔 Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 ...
- BZOJ 1038 瞭望塔
Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1, ...
- 1038: [ZJOI2008]瞭望塔 - BZOJ
Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1, ...
- bzoj 1038 瞭望塔 半平面交+分段函数
题目大意 给你一座山,山的形状在二维平面上为折线 给出\((x_1,y_1),(x_2,y_2)...(x_n,y_n)\)表示山的边界点或转折点 现在要在\([x_1,x_n]\)(闭区间)中选择一 ...
- bzoj千题计划126:bzoj1038: [ZJOI2008]瞭望塔
http://www.lydsy.com/JudgeOnline/problem.php?id=1038 本题可以使用三分法 将点按横坐标排好序后 对于任意相邻两个点连成的线段,瞭望塔的高度 是单峰函 ...
随机推荐
- 加载cocos studio场景
今天尝试加载cocos studio的场景. 新版的cocos studio中,"导出"选项变成了"发布".发布之后会生成一个res文件夹,其中每个场景有一个. ...
- JS 关闭 页面 浏览器 事件
JS监听关闭浏览器事件关键字: js监听关闭浏览器事件Onunload与OnbeforeunloadOnunload,onbeforeunload都是在刷新或关闭时调用,可以在<script&g ...
- 阿里云修改默认的ssh端口
Linux服务器的ssh服务支持远程访问服务器,默认的ssh端口号是22.为了安全起见,很多用户会将端口号由22改为其他的端口号. 如果遇到修改端口号并重启ssh服务后,新的端口号不生效,请参考以下 ...
- c#:Reflector+Reflexil 修改编译后的dll/exe文件
不知道大家有没有这样的经历:现场实施时测试出一个bug,明明知道某个dll/exe文件只要修改一二行代码即可,但手头没有开发环境,紧急情况下,可以用reflector + reflexil 临时直接修 ...
- java中String、StringBuffer、StringBuilder的区别
java中String.StringBuffer.StringBuilder是编程中经常使用的字符串类,他们之间的区别也是经常在面试中会问到的问题.现在总结一下,看看他们的不同与相同. 1.可变与不可 ...
- 翻译qmake文档(四) Building Common Project Types
翻译qmake文档 目录 本章原英文文档:http://qt-project.org/doc/qt-5/qmake-common-projects.html 构建常见的项目类型 本章描述 ...
- Oracle On 、Where、Having 区别
ON .WHERE.HAVING都能通过限制条件筛选数据,但他们的使用及其不同.下面我们来分析三者之间的区别. 1. ON 和WHERE 所有的查询都回产生一个中间临时报表,查询结果就是从返回临时报表 ...
- Python2.4-原理之函数
此节来自于<Python学习手册第四版>第四部分 一.函数基础 函数的作用在每个编程语言中都是大同小异的,,这个表是函数的相关语句和表达式. 1.编写函数,a.def是可执行代码,pyth ...
- 你真的理解 new 了吗?
开篇先提几个问吧,如果你对这些问题都清楚了,那说明对于 new 这个关键字已经掌握得很好了,也不再需要花时间来阅读本文了, 1 new 一个class 与 new 一个Struct有什么 ...
- 大新闻!HoloLens即将入华商用
昨天微软搞了大新闻,Terry和Alexi到了深圳,在WinHEC大会上宣布了2017上半年HoloLens正式入华商用. 关于HoloLens的技术原理和细节官方文档和报道已经披露很多了,他是一款真 ...