【题目链接】

http://www.lydsy.com/JudgeOnline/problem.php?id=1038

【题意】

找一个最低塔高使可以看到村庄的每一个角落。

【思路】

半平面交

能够看到一个线段的点都在该线段所在直线的上方,如果能看到所有的线段则该区域就是所有线段所在直线的半平面交。

最低塔高就是要求这个区域与村庄之间的最短距离。无论是交还是村庄都可以看作是分段的一次函数,所以最近距离一定在分段点处取得。分别枚举交和村庄的分段点即可。

需要注意的有:预先添加两个边界。求最近距离时先判断一下x的关系,否则谁知道交点飞到哪去T_T

【代码】

 #include<cmath>
#include<cstdio>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std; const int N = ;
const double bond = ;
const double eps = 1e-; struct Pt {
double x,y;
Pt (double x=,double y=):x(x),y(y){}
};
typedef Pt vec; vec operator + (Pt a,Pt b) { return vec(a.x+b.x,a.y+b.y); }
vec operator - (Pt a,Pt b) { return vec(a.x-b.x,a.y-b.y); }
vec operator * (Pt a,double p) { return vec(a.x*p,a.y*p); } double cross(Pt a,Pt b) { return a.x*b.y-a.y*b.x; } struct Line {
Pt p; vec v; double ang;
Line () {}
Line (Pt p,vec v) :p(p),v(v){ ang=atan2(v.y,v.x); }
bool operator < (const Line& rhs) const {
return ang<rhs.ang;
}
}; bool onleft(Line L,Pt p) { return cross(L.v,p-L.p)>; }
Pt LineInter(Line a,Line b)
{
vec u=a.p-b.p;
double t=cross(b.v,u)/cross(a.v,b.v);
return a.p+a.v*t;
}
vector<Pt> HPI(vector<Line> L)
{
int n=L.size();
sort(L.begin(),L.end());
int f,r;
vector<Pt> p(n) , ans;
vector<Line> q(n);
q[f=r=]=L[];
for(int i=;i<n;i++) {
while(f<r&&!onleft(L[i],p[r-])) r--;
while(f<r&&!onleft(L[i],p[f])) f++;
q[++r]=L[i];
if(fabs(cross(q[r].v,q[r-].v))<eps) {
r--;
if(onleft(q[r],L[i].p)) q[r]=L[i];
}
if(f<r) p[r-]=LineInter(q[r-],q[r]);
}
while(f<r&&!onleft(q[f],p[r-])) r--;
if(r-f<=) return ans;
p[r]=LineInter(q[r],q[f]);
for(int i=f;i<=r;i++) ans.push_back(p[i]);
return ans;
} vector<Line> L;
vector<Pt> p,np;
int n; int main()
{
scanf("%d",&n);
double x[N],y[N];
for(int i=;i<=n;i++) {
scanf("%lf",&x[i]);
}
for(int i=;i<=n;i++) {
scanf("%lf",&y[i]);
}
p.push_back(Pt(x[],y[]+));
for(int i=;i<=n;i++) p.push_back(Pt(x[i],y[i]));
p.push_back(Pt(x[n],y[n]+));
for(int i=;i<=n;i++) {
L.push_back(Line(p[i],p[i+]-p[i]));
}
np=HPI(L);
double ans=1e30;
for(int i=;i<np.size();i++)
for(int j=;j<=n;j++) if(np[i].x>=p[j].x&&np[i].x<=p[j+].x) {
Pt x=Pt(np[i].x,-);
x=LineInter(Line(p[j],p[j+]-p[j]),Line(x,np[i]-x));
ans=min(ans,np[i].y-x.y);
}
for(int i=;i<=n;i++)
for(int j=;j<(int)np.size()-;j++) if(p[i].x>=np[j].x&&p[i].x<=np[j+].x) {
Pt x=Pt(p[i].x,-);
x=LineInter(Line(np[j],np[j+]-np[j]),Line(x,p[i]-x));
ans=min(ans,x.y-p[i].y);
}
printf("%.3lf",ans);
return ;
}

bzoj 1038 [ZJOI2008]瞭望塔(半平面交)的更多相关文章

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

    1038: [ZJOI2008]瞭望塔 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2999  Solved: 1227[Submit][Statu ...

  2. BZOJ 1038 ZJOI2008 瞭望塔 半平面交

    题目大意及模拟退火题解:见 http://blog.csdn.net/popoqqq/article/details/39340759 这次用半平面交写了一遍--求出半平面交之后.枚举原图和半平面交的 ...

  3. 【BZOJ 1038】 1038: [ZJOI2008]瞭望塔

    1038: [ZJOI2008]瞭望塔 Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 ...

  4. bzoj 1038 瞭望塔 半平面交+分段函数

    题目大意 给你一座山,山的形状在二维平面上为折线 给出\((x_1,y_1),(x_2,y_2)...(x_n,y_n)\)表示山的边界点或转折点 现在要在\([x_1,x_n]\)(闭区间)中选择一 ...

  5. 「BZOJ1038」「洛谷P2600」「ZJOI2008」瞭望塔 半平面交+贪心

    题目链接 BZOJ/洛谷 题目描述 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安. 我们将H村抽象为一维的轮廓.如下图所示: 我们可以用一条山的上方 ...

  6. 【BZOJ】1038: [ZJOI2008]瞭望塔

    http://www.lydsy.com/JudgeOnline/problem.php?id=1038 题意:给出n个x轴各不相同的二维整点,且升序,n<=300,坐标绝对值<=10^6 ...

  7. 1038: [ZJOI2008]瞭望塔 - BZOJ

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

  8. 1038: [ZJOI2008]瞭望塔

    半平面交. 半平面指的就是一条直线的左面(也不知道对不对) 半平面交就是指很多半平面的公共部分. 这道题的解一定在各条直线的半平面交中. 而且瞭望塔只可能在各个点或者半平面交折线的拐点处. 求出半平面 ...

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

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

随机推荐

  1. Coder-Strike 2014 - Round 1(A~E)

    题目链接 A. Poster time limit per test:1 secondmemory limit per test:256 megabytesinput:standard inputou ...

  2. [itint5]堆放积木

    先按照一维排序,然后在第二维求最大上升子序列.注意比较的时候还要考虑第一维虽然排序,还是有可能相等的. bool comp(const Box &a, const Box &b) { ...

  3. ZOJ1204——Additive equations(DFS)

    Additive equations Description We all understand that an integer set is a collection of distinct int ...

  4. 理解extern char s[100]与extern char *s

    在x.c中定义了一个字符数组 char s[100],在l.c中进行引用extern char s[200], 有些c程序新手经常把它写成extern char *s. 这两种写法的含义一样吗? 首先 ...

  5. 如何提高Web服务端并发效率的异步编程技术

    作为一名web工程师都希望自己做的web应用能被越来越多的人使用,如果我们所做的web应用随着用户的增多而宕机了,那么越来越多的人就会变得越来越少了,为了让我们的web应用能有更多人使用,我们就得提升 ...

  6. Ubuntu 安装Android Studio与使用手册

    用的是Ubuntu 12.04 1.先去下载,国内可以去这里下载 https://github.com/inferjay/AndroidDevTools 2.下载后解压进入android-studio ...

  7. (转)Redis与Memcached的区别

    如果简单地比较Redis与Memcached的区别,大多数都会得到以下观点: 1 Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,hash等数据结构的存储. 2 Redis支持 ...

  8. Use powerful plugins in your vim.

    # setup by root wget http://prdownloads.sourceforge.net/ctags/ctags-5.8.tar.gz tar -xzvf ctags-5.8.t ...

  9. Oracle EBS Report 输出字符字段前部"0"被Excel自动去掉问题

    Oracle  EBS 提供多种报表的开发和输出形式,由于MS Excel在处理数据方面的优势明显,报表输出用Excel打开是很常见的开发项. 但是正是由于Excel的"过于智能而不智能&q ...

  10. Pomelo服务器琐碎方法

    1.获取客户端ip地址:session__session__.__socket__remoteAddress.ip 2.日志文件无法打印到文件,删除node_modules/pomelo/node_m ...