【BZOJ】【1038】【ZJOI2008】瞭望塔
计算几何/半平面交
说是半平面交,实际上只是维护了个下凸壳而已……同1007水平可见直线
对于每条线段,能看到这条线段的点都在这条线段的“上方”,那么对所有n-1条线段求一个可视区域的交,就是求一个半平面交……(好扯)
一开始我想的是:直接找到这个下凸壳的最低点,它的y值就是答案辣~但是明显不对>_>这题让求的是塔的最低高度……不光要考虑塔顶,还要看塔底的啊!
那么我们怎么找呢?我们可以发现:随着x的变化,塔高(就是地面到凸壳的竖直距离,y坐标之差)是一个分段函数,分段点就是地面的折点以及凸壳的顶点!而且在每一段里面,塔高的值是一个一次函数!经过大胆猜想,小(bu)心(yong)证明我们发现:分段一次函数的极值在分段点和边界点处取到。
那么就是对这些点算一下答案就可以了……点数是O(n)的……
- /**************************************************************
- Problem: 1038
- User: Tunix
- Language: C++
- Result: Accepted
- Time:0 ms
- Memory:1292 kb
- ****************************************************************/
- //BZOJ 1038
- #include<cmath>
- #include<vector>
- #include<cstdio>
- #include<cstring>
- #include<cstdlib>
- #include<iostream>
- #include<algorithm>
- #define rep(i,n) for(int i=0;i<n;++i)
- #define F(i,j,n) for(int i=j;i<=n;++i)
- #define D(i,j,n) for(int i=j;i>=n;--i)
- #define pb push_back
- using namespace std;
- inline int getint(){
- int v=,sign=; char ch=getchar();
- while(ch<''||ch>''){ if (ch=='-') sign=-; ch=getchar();}
- while(ch>=''&&ch<=''){ v=v*+ch-''; ch=getchar();}
- return v*sign;
- }
- const int N=,INF=~0u>>;
- typedef long long LL;
- typedef double lf;
- const lf eps=1e-;
- /******************tamplate*********************/
- struct Point{
- lf x,y;
- void read(){scanf("%lf%lf",&x,&y);}
- }p[N];
- struct Line{double k,b;}l[N],st[N];
- Line make_line(Point a,Point b){
- Line tmp;
- tmp.k=(a.y-b.y)/(a.x-b.x);
- tmp.b=a.y-tmp.k*a.x;
- return tmp;
- }
- int n,top;
- inline bool cmp(Line a,Line b){
- if (fabs(a.k-b.k)<eps) return a.b<b.b;
- return a.k<b.k;
- }
- double crossx(Line x1,Line x2){
- return (x2.b-x1.b)/(x1.k-x2.k);
- }
- void insert(Line a){
- while(top){
- if (fabs(st[top].k-a.k)<eps) top--;
- else if (top> && crossx(a,st[top-])<=
- crossx(st[top],st[top-])) top--;
- else break;
- }
- st[++top]=a;
- }
- lf Up(lf x){
- lf ans=0.0;
- F(i,,top)
- ans=max(ans,st[i].k*x+st[i].b);
- return ans;
- }
- lf Down(lf x){
- int pos;
- for(pos=;pos<n && p[pos+].x<x;pos++);
- if (pos==n) return -1e10;
- Line tmp=make_line(p[pos],p[pos+]);
- return tmp.k*x+tmp.b;
- }
- int main(){
- #ifndef ONLINE_JUDGE
- freopen("1038.in","r",stdin);
- freopen("1038.out","w",stdout);
- #endif
- n=getint();
- F(i,,n) scanf("%lf",&p[i].x);
- F(i,,n) scanf("%lf",&p[i].y);
- F(i,,n-) l[i]=make_line(p[i+],p[i]);
- sort(l+,l+n,cmp);
- F(i,,n-) insert(l[i]);
- lf ans=1e10;
- F(i,,n) ans=min(ans,Up(p[i].x)-p[i].y);
- F(i,,top){
- Point p;
- p.x=crossx(st[i-],st[i]);
- p.y=st[i].k*p.x+st[i].b;
- ans=min(ans,p.y-Down(p.x));
- }
- printf("%.3lf\n",ans);
- return ;
- }
1038: [ZJOI2008]瞭望塔
Time Limit: 10 Sec Memory Limit: 162 MB
Submit: 1043 Solved: 470
[Submit][Status][Discuss]
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
HINT
对于100%的数据, N ≤ 300,输入坐标绝对值不超过106,注意考虑实数误差带来的问题。
Source
【BZOJ】【1038】【ZJOI2008】瞭望塔的更多相关文章
- bzoj 1038 [ZJOI2008]瞭望塔(半平面交)
[题目链接] http://www.lydsy.com/JudgeOnline/problem.php?id=1038 [题意] 找一个最低塔高使可以看到村庄的每一个角落. [思路] 半平面交 能够看 ...
- BZOJ 1038 ZJOI2008 瞭望塔 半平面交
题目大意及模拟退火题解:见 http://blog.csdn.net/popoqqq/article/details/39340759 这次用半平面交写了一遍--求出半平面交之后.枚举原图和半平面交的 ...
- 【BZOJ 1038】 1038: [ZJOI2008]瞭望塔
1038: [ZJOI2008]瞭望塔 Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 ...
- 1038: [ZJOI2008]瞭望塔 - BZOJ
Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1, ...
- 1038: [ZJOI2008]瞭望塔
半平面交. 半平面指的就是一条直线的左面(也不知道对不对) 半平面交就是指很多半平面的公共部分. 这道题的解一定在各条直线的半平面交中. 而且瞭望塔只可能在各个点或者半平面交折线的拐点处. 求出半平面 ...
- 【BZOJ】1038: [ZJOI2008]瞭望塔
http://www.lydsy.com/JudgeOnline/problem.php?id=1038 题意:给出n个x轴各不相同的二维整点,且升序,n<=300,坐标绝对值<=10^6 ...
- bzoj千题计划126:bzoj1038: [ZJOI2008]瞭望塔
http://www.lydsy.com/JudgeOnline/problem.php?id=1038 本题可以使用三分法 将点按横坐标排好序后 对于任意相邻两个点连成的线段,瞭望塔的高度 是单峰函 ...
- [BZOJ1038][ZJOI2008]瞭望塔(半平面交)
1038: [ZJOI2008]瞭望塔 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2999 Solved: 1227[Submit][Statu ...
- 【BZOJ1038】[ZJOI2008]瞭望塔 半平面交
[BZOJ1038][ZJOI2008]瞭望塔 Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如 ...
- 【BZOJ 1038】[ZJOI2008]瞭望塔
[题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1038 [题意] [题解] 可以看到所有村子的瞭望塔所在的位置只会是在相邻两个村子所代表 ...
随机推荐
- USACO 5.5 Twofive
TwofiveIOI 2001 In order to teach her young calvess the order of the letters in the alphabet, Bessie ...
- PyQt5调入数据库数据在表格中显示
数据库为Postgresql import sys from form import Ui_Form from PyQt5.Qt import QWidget, QApplication,QTable ...
- python安装pip和使用pip安装Python库类比如pip安装beautifulsoup4
初学Python时,看到很多不懂得东西,比如 pip, 是python 包管理工具,pip是easy_install的取代. Distribute是对标准库disutils模块的增强,我们知道disu ...
- 有关Virtualbox虚拟机增强功能安装的问题
在老师给定的步骤下并不能正常的完成Virtualbox虚拟机增强功能安装而是显示下图
- CSS 显示或隐藏子元素
很多时候我们仅仅只是想让鼠标移动入某个元素,然后显示出某个元素. 大多数博客的标题或内容都是:使用CSS实现鼠标悬停在一行上,显示某些元素 很遗憾,这是错误的,鼠标悬停后,尽管CSS标准中有定义此种方 ...
- python使用web.py开发httpserver,解决post请求跨域问题
使用web.py做http server开发时,遇到postman能够正常请求到数据,但是浏览器无法请求到数据,查原因之后发现是跨域请求的问题. 跨域请求,就是在浏览器窗口中,和某个服务端通过某个 “ ...
- 汉化 的 空指针 bug
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha nulljava.lang.NullPointerException at com.an ...
- AtCoder Grand Contest 019 F-yes or no
AtCoder Grand Contest 019 F-yes or no 解题思路: 考虑一个贪心策略,假设当前还有 \(x\) 道 \(\text{yes}\) 和 \(y\) 道 \(\text ...
- Codeforces Round #222 (Div. 1) C. Captains Mode 状压
C. Captains Mode 题目连接: http://codeforces.com/contest/377/problem/C Description Kostya is a progamer ...
- 读书笔记_Effective_C++_条款三十三:避免遮掩继承而来的名称
名称的遮掩可以分成变量的遮掩与函数的遮掩两类,本质都是名字的查找方式导致的,当编译器要去查找一个名字时,它一旦找到一个相符的名字,就不会再往下去找了,因此遮掩本质上是优先查找哪个名字的问题. 而查找是 ...