【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 正解半平面交在另一篇里面 ...
随机推荐
- button上加上图片的两种方式
//// ViewController.m// UIButtonDemo//// Created by hehe on 15/9/15.// Copyright (c) 2015年 wang. ...
- The influence of informal governance mechanisms on knowledge integration
Title:The influence of informal governance mechanisms on knowledge integration within cross-function ...
- ViewPager的简单例子
这个例子是按照官网上的例子写的,有点抄袭的嫌疑,但是自己单独写一下会加深自己的印象. 首先是MainAcitivity.xml: <LinearLayout xmlns:android=&quo ...
- blazeDS集成spring的remote访问
欢迎交流转载,请注明出处:http://www.cnblogs.com/shizhongtao/p/3490037.html 上一篇我只是简单实用blazeds创建了一个实例,大多数开发中,都是结合 ...
- Fuck Flyme Theme
转载说明 本篇文章可能已经更新,最新文章请转:http://www.sollyu.com/fuck-flyme-theme/ 说明 本插件仅用于魅蓝Note, MX3, MX4, MX4 PRO它机型 ...
- jQuery实例—选项卡(js源码和jQuery)【一些常见方法(1)-练习】
分别利用javascript的源码和jQuery来实现一个简单的选项卡,对比各自的步骤. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Tr ...
- linux下挂载移动硬盘ntfs格式
http://jingyan.baidu.com/article/f96699bba93dce894e3c1bec.html fdisk -l安装后 使用命令mount -t ntfs-3g /dev ...
- ecshop订单中配送方式报错
警告内容:Warning: number_format() expects parameter 1 to be double, string given in D:\wamp\www\ecshop_o ...
- vb6-很简单的配置密码验证提示
'很简单的配置密码验证提示 Dim add As String add = Trim(InputBox("请输入配置密码", "报表配置")) If add = ...
- 拥抱ARM妹子 序章!ARM妹子~~ 哥我来啦!
一个负心汉即将移情别恋,从51转到ARM妹子啦?其实8是的,俺准备开后宫.哇——咔~咔~~.考虑功耗和成本等问题,只有51肯定是不够的,所以嘛~~(一脸坏笑)嘿嘿~~,ARM妹子俺追定了.出于对ARM ...