题目:

  

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

N ≤ 300,输入坐标绝对值不超过106,注意考虑实数误差带来的问题。


题解:

这里引用神犇我是傻叉(这名字··)的题解,ORZ,附上链接:http://blog.csdn.net/qpswwww/article/details/44105605

  

这个题在上海ACM/ICPC冬令营的比赛中也考过,不是很难,不过想要想到用半平面交来搞还是不容易的。 
 
如上图,手模下可以发现一个点要想看到所有的山顶,肯定是要在相邻两个山顶连线的半平面交中。那么显然这个相对高度最小的点肯定是在半平面交的边界上,因此有如下两种情况: 
1、这个点在半平面交边界上两个直线的交点处(代码中的calc2()) 
2、这个点在某个山顶在半平面交的边界的投影处(代码中的calc1()) 
可以脑补下,答案对应的点肯定是这两种情况之一,至于证明嘛。。。实在难以表述出来(谁会证明的请告诉我,感激不尽)

然后在代码的实现上偷了点小懒。。。之前翻其他人题解,无非就是两种做法:1、解析几何法求直线交点,2、叉积+定比分点公式求交,考虑到这个题的题面已经限制了没有两条直线垂直的情况(x1<x2<...<xn),加上最后要求相对高度时用解析几何法来得方便些,于是你懂的。

心得:

  直线半平面交的经典题··和赛车有点相似之处,但tm又老wa一个点啊,md半平面交存心和我过不去吗?QWQ

另外还发现了一个写了赛车以来一直有的一个误解····就是凸多边形那个弹出check的方法是通用的!!!,赛车那道题是因为所有线都是射线!!所以可以那样化简而已,QWQ;

代码:

  

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<string>
#include<ctime>
#include<cmath>
#include<algorithm>
#include<cctype>
#include<iomanip>
#define double long double
using namespace std;
int n,cnt,tot;
double ans;
struct P{double x,y;
}p[3000],a[3000];
P vec(P a,P b){P s;s.x=a.x-b.x;s.y=a.y-b.y;return s;
}
double xplus(P a,P b){return a.x*b.y-b.x*a.y;
}
struct L{P a,b;double slope;friend bool operator < (L aa,L ab){if(aa.slope!=ab.slope) return aa.slope<ab.slope;else return xplus(vec(aa.b,aa.a),vec(ab.b,aa.a))>0;}
}l[3000],que[3000];
P inter(L a,L b){double k1,k2,t;k1=xplus(vec(b.b,a.a),vec(a.b,a.a));k2=xplus(vec(a.b,a.a),vec(b.a,a.a));t=k1/(k1+k2);P ret;ret.x=b.b.x+t*(b.a.x-b.b.x);ret.y=b.b.y+t*(b.a.y-b.b.y);return ret;
}
bool check(L a,L b,L t){P s=inter(a,b);return xplus(vec(t.b,t.a),vec(s,t.a))<0;
}
void preact(){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);return ;
}
void hpi(){int ll=1,rr=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;tot=0;que[++rr]=l[1],que[++rr]=l[2];for(int i=3;i<=cnt;++i){while(ll<rr&&check(que[rr-1],que[rr],l[i])) --rr;while(ll<rr&&check(que[ll+1],que[ll],l[i])) ++ll;que[++rr]=l[i];}while(ll<rr&&check(que[rr-1],que[rr],que[ll])) --rr;while(ll<rr&&check(que[ll+1],que[ll],que[rr])) ++ll;for(int i=ll;i<rr;++i)a[++tot]=inter(que[i],que[i+1]);return ;
}
void getans(){for(int i=1;i<=tot;++i){P posnow;posnow.x=a[i].x;posnow.y=-1;for(int j=1;j<n;++j)if(a[i].x>=p[j].x&&a[i].x<=p[j+1].x)ans=min(ans,a[i].y-inter((L){p[j],p[j+1]},(L){posnow,a[i]}).y);}for(int i=1;i<=n;++i){P nowpos;nowpos.x=p[i].x;nowpos.y=-1;for(int j=1;j<tot;++j)if(a[j].x<=p[i].x&&a[j+1].x>=p[i].x)ans=min(ans,inter((L){a[j],a[j+1]},(L){nowpos,p[i]}).y-p[i].y);}return ;
}
inline int read(){int i=0,f=1;char ch;for(ch=getchar();ch>'9'||ch<'0';ch=getchar())if(ch=='-') f=-1;for(;ch>='0'&&ch<='9';ch=getchar())i=(i<<3)+(i<<1)+(ch^48);return i*f;
}
int main(){n=read();ans=1e60;for(int i=1;i<=n;++i)p[i].x=read();for(int i=1;i<=n;++i)p[i].y=read();preact();hpi();getans();printf("%.3Lf",ans);return 0;
}

  

转载于:https://www.cnblogs.com/AseanA/p/6622230.html

刷题总结——瞭望塔(bzoj1038)相关推荐

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

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

  2. bzoj1038 [ZJOI2008]瞭望塔(半平面交)

    bzoj1038 [ZJOI2008]瞭望塔 原题地址:http://www.lydsy.com/JudgeOnline/problem.php?id=1038 题意: 村中要建立一个瞭望塔,我们将H ...

  3. bzoj1038 [ZJOI2008]瞭望塔

    Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们 将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1 ...

  4. bzoj1038 瞭望塔

    传送门 有一个坑点,就是给出的点共线.在加点的时候要判一下就行.剩下的就是半平面交. 有两种情况:瞭望塔的一个端点在半平面的交点上,另一端在山上. 或者一个端点在山上,另一个端点在半平面上. 由于n& ...

  5. [BZOJ1038][ZJOI2008]瞭望塔(半平面交)

    题目: 我是超链接 题解: 很显然,只有瞭望塔和每个山顶形成直线的斜率的绝对值大于对应山坡的斜率,这个山坡才能看见.不难想到对所有的山坡求一个半平面交然后找到有山顶存在的部分,这个n<=300也 ...

  6. bzoj1038【ZJOI2008】瞭望塔

    1038: [ZJOI2008]瞭望塔 Time Limit: 10 Sec  Memory Limit: 162 MB Submit: 1628  Solved: 709 [Submit][Stat ...

  7. bzoj1038: [ZJOI2008]瞭望塔

    Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们 将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1 ...

  8. 【ZJOI2008】【BZOJ1038】瞭望塔

    Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1, ...

  9. BZOJ第一页刷题计划

    BZOJ第一页刷题计划 已完成:67 / 90 [BZOJ1000]A+B Problem:A+B: [BZOJ1001][BeiJing2006]狼抓兔子:最小割: [BZOJ1002][FJOI2 ...

最新文章

  1. 【云计算】_8云视频与通信服务(完结)
  2. c语言文件打开函数,C语言fopen函数中文件打开方式(参数值)
  3. 晨读,难道只是为了完成任务而读的吗?
  4. 第一百一十期:详解SpringBoot应用跨域访问解决方案
  5. linux PCI驱动调用字符设备驱动方式
  6. phpcms 首页调用不同栏目的指定文章id 的content等内容 - 方法篇
  7. postgreSQL源码分析——索引的建立与使用——B-Tree索引(3)
  8. rsa解密的应用_安全-加解密
  9. Linux---线程池的实现
  10. C++数字与字符串的相互转换
  11. nginx启动vue_Docker部署前端Vue
  12. Typora 下载及使用简介
  13. 面向程序员的精品开源字体
  14. 题目 1548: 盾神与砝码称重
  15. 谈谈我了解的那些在线it学习网站
  16. android camera使用ISO值录制视频
  17. Python: PS 图像调整--颜色梯度
  18. 测试种类大汇总(45类)
  19. Q for Mortals2笔记 -- 函数
  20. abb机器人开通选项_ABB工业机器人系统选项全面介绍--ABB机器人

热门文章

  1. FluentNhibernate 组件component及应用
  2. iOS Universal Links 配置教程
  3. 网络连接的net命令
  4. 原生js实现三级联动
  5. Spring4 事务管理
  6. [唐诗]正月十五日夜-苏味道
  7. [HTTP] Nginx代理以及面向未来的HTTP
  8. [jQuery基础] jQuery节点操作
  9. 物联网专题--基于APP Inventor的BLE蓝牙4.0数据通信
  10. 机器学习算法(8)——朴素贝叶斯、最小风险贝叶斯决策