【BZOJ 1038】 1038: [ZJOI2008]瞭望塔
1038: [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 0Sample Output
【输出样例一】
1.000
【输出样例二】
14.500HINT
N ≤ 300,输入坐标绝对值不超过106,注意考虑实数误差带来的问题。
【分析】
还没有AC就打题解真的好?【默默对拍中。。
题目里面没有图,奉献一幅可爱的图?(这是样例1)

绿色是山,紫色是可行域,红色的是最小的塔高。
这题感觉吧跟多边形的核差不多,我们把轮廓线转换成半平面求角,然后考虑轮廓和半平面交的顶点(可以证明这里面一定存在最优塔高),
从这个顶点垂直于x轴延伸求出塔高,然后计算最小值就好了。
【1分钟后....
终于AC了,啊啊啊范围弄小了。。。。。10^6不是范围【没有听PO姐话就傻逼了一下
打半平面交的时候真是超级多错,最好弄eps搞精度。
然后注意轮廓和半平面交的边界(求塔高的时候不要越界,会有问题的)
就酱,真的是一周一题的缓慢速度。。。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
#define Maxn 310 double INF=1e60;
const double eps=0.000001; struct P {double x,y;};
struct LN {P a,b;double slop;}l[Maxn],p[Maxn]; double sx[Maxn],sy[Maxn];
int n; P operator - (P x,P y)
{
P tt;
tt.x=x.x-y.x;
tt.y=x.y-y.y;
return tt;
} P operator + (P x,P y)
{
P tt;
tt.x=x.x+y.x;
tt.y=x.y+y.y;
return tt;
} P operator * (P x,double y)
{
P tt;
tt.x=x.x*y;
tt.y=x.y*y;
return tt;
} double Cross(P x,P y) {return x.x*y.y-x.y*y.x;}
double Dot(P x,P y) {return x.x*y.x+x.y*y.y;} bool operator < (LN x,LN y) {return (x.slop==y.slop)?(Cross(x.b-x.a,y.b-x.a)<):(x.slop<y.slop);} P inter(LN x,LN y)
{
P nw=y.a-x.a;
double tt;
P X=x.b-x.a,Y=y.b-y.a;
tt=Cross(nw,X)/Cross(X,Y);
return y.a+Y*tt;
} bool jud(LN x,LN y,LN z)
{
P nw=inter(x,y);
if(Cross(z.b-z.a,nw-z.a)<eps&&Cross(z.b-z.a,nw-z.a)>-eps) return ;
return Cross(z.b-z.a,nw-z.a)<;
} int cnt;
void op()
{
for(int i=;i<=cnt;i++)
{
printf("%.2lf %.2lf %.2lf %.2lf = %.2lf\n",l[i].a.x,l[i].a.y,l[i].b.x,l[i].b.y,l[i].slop);
}printf("\n");
} void opp(int L,int R)
{
for(int i=L;i<=R;i++)
{
printf("%.2lf %.2lf %.2lf %.2lf = %.2lf\n",p[i].a.x,p[i].a.y,p[i].b.x,p[i].b.y,p[i].slop);
}printf("\n");
} P as[Maxn];
int L,R; bool ffind()
{
for(int i=;i<=n;i++) l[i].slop=atan2(l[i].b.y-l[i].a.y,l[i].b.x-l[i].a.x);
sort(l+,l++n); cnt=;
for(int i=;i<=n;i++)
{
if(l[i].slop!=l[cnt].slop) l[++cnt]=l[i];
}
// op();
L=,R=;
p[]=l[];p[]=l[];
// opp(L,R);
if(cnt<) return ;
for(int i=;i<=cnt;i++)
{
while(R>L&&jud(p[R],p[R-],l[i])) R--;
while(R>L&&jud(p[L],p[L+],l[i])) L++;
p[++R]=l[i];
// opp(L,R);
}
if(R>L&&jud(p[R],p[R-],p[L])) R--;
// opp(L,R);
if(R-L+<) return ;
return ;
// opp(L,R);
/*double ans=INF;
for(int i=L;i<R;i++)
{
P x=inter(p[i],p[i+1]);
ans=ans<x.y?ans:x.y;
}
printf("%.3lf\n",ans);*/
} void get_ans()
{
double ans=INF;
int ft=L;
P fx=inter(p[L],p[L+]);
for(int i=;i<=n+;i++)
{
while(sx[i]>=fx.x&&ft<R)
{
ft++;
fx=inter(p[ft],p[ft+]);
}
LN nw;
nw.a.x=sx[i];nw.a.y=sy[i];
nw.b.x=sx[i];nw.b.y=sy[i]+;
P xx=inter(nw,p[ft]);
ans=ans<xx.y-sy[i]?ans:xx.y-sy[i];
// printf("==%.2lf\n",xx.y-sy[i]);
}
// printf("--%.2lf\n",ans); ft=;
LN now;
now.a.x=sx[];now.a.y=sy[];
now.b.x=sx[];now.b.y=sy[];
for(int i=L;i<R;i++)
{
P x=inter(p[i],p[i+]);
if(x.x<sx[]) continue;
while(x.x>=sx[ft+])
{
ft++;
if(ft>n) break;
// now.a.x=sx[ft];now.a.y=sy[ft];
now.a=now.b;
now.b.x=sx[ft+];now.b.y=sy[ft+];
}
if(ft>n) break;
LN nw;
nw.a=nw.b=x;nw.b.y=nw.b.y+;
P xx=inter(nw,now);
ans=ans<x.y-xx.y?ans:x.y-xx.y;
// printf("==%.2lf\n",x.y-xx.y);
}
if(ans>=-eps&&ans<=eps) printf("0.000\n");
else printf("%.3lf\n",ans);
} int main()
{
scanf("%d",&n);
for(int i=;i<=n;i++) scanf("%lf",&sx[i]);
for(int i=;i<=n;i++) scanf("%lf",&sy[i]);
n--;
for(int i=;i<=n;i++)
{
l[i].a.x=sx[i];l[i].a.y=sy[i];
l[i].b.x=sx[i+];l[i].b.y=sy[i+];
}
if(!ffind()) printf("0.000\n");
else get_ans();
return ;
}
做几何题真的就不删调试了。
2016-12-29 17:09:28
【BZOJ 1038】 1038: [ZJOI2008]瞭望塔的更多相关文章
- 【BZOJ 1038】[ZJOI2008]瞭望塔
[题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1038 [题意] [题解] 可以看到所有村子的瞭望塔所在的位置只会是在相邻两个村子所代表 ...
- 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村抽象为一维的轮廓.如 ...
- 1038: [ZJOI2008]瞭望塔 - BZOJ
Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1, ...
- 1038: [ZJOI2008]瞭望塔
半平面交. 半平面指的就是一条直线的左面(也不知道对不对) 半平面交就是指很多半平面的公共部分. 这道题的解一定在各条直线的半平面交中. 而且瞭望塔只可能在各个点或者半平面交折线的拐点处. 求出半平面 ...
- bzoj1038: [ZJOI2008]瞭望塔
Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1, ...
- [ZJOI2008]瞭望塔
题目描述 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安. 我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1, y1), ...
- [日常摸鱼]bzoj1038 [ZJOI2008]瞭望塔-模拟退火/几何
题意:给一条平面内$n$个点的折线,要求在折线上搞一个高度$h$的瞭望塔,能够看见折线上所有的点,求$h$的最小值($n \leq 300$) updata2018.1.21 正解半平面交在另一篇里面 ...
随机推荐
- Eclipse JavaEE设置内置浏览器和外部浏览器
Eclipse JavaEE设置内置浏览器和外部浏览器 我们在使用Java EE版本的Eclipse开发Java Web程序时,Eclipse会有一个默认的内置浏览器查看网页的效果,如下图 但是内置浏 ...
- @override
目录 用处 作用 注意 用处: 继承抽象类,必须实现抽象方法,方法上要加@override 实现接口时,必须实现接口里定义的方法,方法上要加@override 作用: 可以检查方法 ...
- 算法 replace,replace_copy,back_inserter
replace (list.begin(), list.end(), , ); // replace any elements with value of 0 by 42 replace算法对输入序列 ...
- NSS_01 开始
工作中一直使用asp.net webform, 最近有一个新的小项目, 决定用asp.net mvc3, 边学习边工作吧,记录一下开发过程中的问题,因为工作嘛,只记录问题,可能不会很详细. 准备使用a ...
- 【转】DataGridView之为每行前面添加序号
//最简单的方法是在Datagridview的事件RowPostPaint事件下面添加如下代码即可 private void dataGridView1_RowPostPaint(object sen ...
- RHEL 7.2 安装Oracle XE-11.2.0
轻量快捷版本,适合开发 0. /etc/hosts 添加 本机hostname # hostnamepromote.cache-dns.local # cat /etc/hosts127.0.0.1 ...
- PHP的$_SERVER['HTTP_HOST']获取服务器地址功能详解
uchome的index文件中的二级域名功能判断,使用了php的$_SERVER['HTTP_HOST'],开始对这个不是很了解,所以百度了一下,发现一篇帖子有点意思,转发过来做个记录. 在php中, ...
- 《PHP与MySQL WEB开发》读书笔记
<PHP与MySQL WEB开发>读书笔记 作者:[美]Luke Welling PHP输出的HereDoc语法: echo <<<theEnd line 1 line ...
- Oracle Lock 概述
按锁的机制分类 排他锁( X ):如果事务T对对象A加上排他锁,则只允许T对A对象读取和修改,其他事务不能对A增加任何锁,直到T释放加载A上的排他锁 共享锁( S ):如果事务T对表A加上共享锁,则事 ...
- python中文件的复制
python中文件的复制 python的os模块有很多文件目录相关的函数,但没有提供直接复制文件的函数,当然可以通过边都边写的方式复制文件.想要直接复制文件可以通过shutil模块 shutil模块是 ...