【BZOJ1038】[ZJOI2008]瞭望塔 半平面交
【BZOJ1038】[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
HINT
N ≤ 300,输入坐标绝对值不超过106,注意考虑实数误差带来的问题。
题解:首先能看到所有位置的点一定在这些折线的上半平面交上,现在问题就变成了在半平面交和下面的折线上各选择一个横坐标相同的点使得两点间距离最小。因为上下都是折线,那么最小值一定是在某个折线的拐点处取到,那么只需要将这些拐点都扫一遍即可。
为了方便,我们需要添加3条辅助线(上,左,右)来限制边界,注意3条线的斜率不能相同。
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
typedef long double ld;
const int maxn=310;
const ld eps=1e-10;
int n,m,h,t;
int q[maxn];
ld ans;
struct point
{
ld x,y;
point (){}
point (ld a,ld b){x=a,y=b;}
point operator + (const point &a) const {return point(x+a.x,y+a.y);}
point operator - (const point &a) const {return point(x-a.x,y-a.y);}
ld operator * (const point &a) const {return x*a.y-y*a.x;}
point operator * (const ld &a) const {return point(x*a,y*a);}
}v[maxn],p[maxn];
struct line
{
point p,v;
ld a;
line() {}
line(point x,point y) {p=x,v=y,a=atan2(v.y,v.x);} }l[maxn];
point getp(line l1,line l2)
{
point u=l1.p-l2.p;
ld temp=(l2.v*u)/(l1.v*l2.v);
return l1.p+l1.v*temp;
}
bool onlft(line a,point b)
{
return a.v*(b-a.p)>eps;
}
bool cmpl(line a,line b)
{
if(fabs(a.a-b.a)<eps) return onlft(a,b.p);
return a.a<b.a;
}
bool cmpp(point a,point b)
{
return a.x<b.x;
}
void HPI()
{
sort(l+1,l+n+3,cmpl);
int i,cnt=0;
for(i=2,cnt=1;i<=n+2;i++) if(fabs(l[i].a-l[cnt].a)>eps) l[++cnt]=l[i];
h=t=q[1]=1;
for(i=2;i<=cnt;i++)
{
while(h<t&&onlft(l[i],getp(l[q[t]],l[q[t-1]]))) t--;
while(h<t&&onlft(l[i],getp(l[q[h]],l[q[h+1]]))) h++;
q[++t]=i;
}
while(h<t&&onlft(l[q[h]],getp(l[q[t]],l[q[t-1]]))) t--;
while(h<t&&onlft(l[q[t]],getp(l[q[h]],l[q[h+1]]))) h++;
q[++t]=q[h];
for(i=h;i<t;i++) p[++m]=getp(l[q[i]],l[q[i+1]]);
sort(p+1,p+m+1,cmpp);
}
void calc(point x,point a,point b)
{
point c;
if(fabs(x.x-a.x)<eps) c=a;
else c=a+(b-a)*((x.x-a.x)/(b.x-a.x));
ld dis=fabs(c.y-x.y);
ans=min(ans,dis);
}
inline int rd()
{
int ret=0,f=1; char gc=getchar();
while(gc<'0'||gc>'9') {if(gc=='-')f=-f; gc=getchar();}
while(gc>='0'&&gc<='9') ret=ret*10+gc-'0',gc=getchar();
return ret*f;
}
int main()
{
n=rd();
int i,j;
for(i=1;i<=n;i++) v[i].x=rd();
for(i=1;i<=n;i++) v[i].y=rd();
for(i=1;i<n;i++) l[i]=line(v[i+1],v[i]-v[i+1]);
l[n].p=point(0,1e25),l[n].v=point(1e7,1);
l[n+1].p=point(-1,0),l[n+1].v=point(1,1e25);
l[n+2].p=point(1e7,1e25),l[n+2].v=point(-1e25,-2);
HPI(),ans=1e25;
for(i=1,j=2;i<=n;i++)
{
for(;p[j].x<v[i].x;j++)
calc(p[j],v[i-1],v[i]);
if(j>2)
calc(v[i],p[j-1],p[j]);
}
printf("%.3Lf",ans);
return 0;
}
【BZOJ1038】[ZJOI2008]瞭望塔 半平面交的更多相关文章
- [BZOJ1038][ZJOI2008]瞭望塔(半平面交)
1038: [ZJOI2008]瞭望塔 Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 2999 Solved: 1227[Submit][Statu ...
- bzoj千题计划126:bzoj1038: [ZJOI2008]瞭望塔
http://www.lydsy.com/JudgeOnline/problem.php?id=1038 本题可以使用三分法 将点按横坐标排好序后 对于任意相邻两个点连成的线段,瞭望塔的高度 是单峰函 ...
- 「BZOJ1038」「洛谷P2600」「ZJOI2008」瞭望塔 半平面交+贪心
题目链接 BZOJ/洛谷 题目描述 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安. 我们将H村抽象为一维的轮廓.如下图所示: 我们可以用一条山的上方 ...
- bzoj 1038 瞭望塔 半平面交+分段函数
题目大意 给你一座山,山的形状在二维平面上为折线 给出\((x_1,y_1),(x_2,y_2)...(x_n,y_n)\)表示山的边界点或转折点 现在要在\([x_1,x_n]\)(闭区间)中选择一 ...
- [日常摸鱼]bzoj1038 [ZJOI2008]瞭望塔-模拟退火/几何
题意:给一条平面内$n$个点的折线,要求在折线上搞一个高度$h$的瞭望塔,能够看见折线上所有的点,求$h$的最小值($n \leq 300$) updata2018.1.21 正解半平面交在另一篇里面 ...
- bzoj1038: [ZJOI2008]瞭望塔
Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1, ...
- BZOJ-1038 [ZJOI2008]瞭望塔
先求半平面交,然后建塔的地方肯定是在半平面交的交点上或者是在地面线段的交点上. #include <cstdlib> #include <cstdio> #include &l ...
- [日常摸鱼]bzoj1038[ZJOI2008]瞭望塔-半平面交
这回好好用半平面交写一次- 看了cls当年写的代码看了好久大概看懂了-cls太强辣 #include<cstdio> #include<iostream> #include&l ...
- 【半平面交】bzoj1038 [ZJOI2008]瞭望塔
http://m.blog.csdn.net/blog/qpswwww/44105605 #include<cstdio> #include<cmath> #include&l ...
随机推荐
- MySql中LongText字段对应Hibernate映射文件的设置(转)
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hi ...
- 关于在SSH2中使用ajax技术的总结(主要写Struts2和ajax)
以下内容是自己理解的,因为还没有看过相关的文章,所以,技术上还是有很大的欠缺.不过这也是自己努力思考得到的,如果有什么更好的建议可以回复我. 1. 任务需求: 实现一个包含数据的表格,并且有分页功能. ...
- json格式在线解析
地址:https://www.bejson.com/ { "PN": "123456", "DomainName": ".gxyc ...
- Java的身份证号码工具类
/** * Copyright (C) 2009-2010 Yichuan, Fuchun All rights reserved. * Licensed to the Apache Software ...
- Spring IoC Container and Spring Bean Example Tutorial
Spring Framework is built on the Inversion of Control (IOC) principle. Dependency injection is the t ...
- linux下c,c++头文件的路径
一. C语言包含的目录: 二. C++包含的目录
- 转:MVVM的基本入门简介
https://mp.weixin.qq.com/s?__biz=MzA3MjA4NjE3NQ==&mid=404502568&idx=1&sn=fe512f9820b99d3 ...
- 【ecshop---新增包邮卡功能】
一:需求分析 项目组要求新增类似虚拟卡的包邮卡,用户获得包邮卡的方式包括后台发送和前台自助充值.包邮卡有使用期限.订单使用包邮卡免除邮费.可以和其他优惠活动同时进行! 二:开发功能点 后台:新增包邮卡 ...
- 微信小程序 - .gitignore失效问题
-------------------------------------------- Last Update Date:2018-8-8 ----------------------------- ...
- 【MVC4】依頼注入
※本文参照<ASP.NET MVC 4高级编程>