[ZJOI2008]瞭望塔
题目描述
致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安。
我们将H村抽象为一维的轮廓。如下图所示
我们可以用一条山的上方轮廓折线(x1, y1), (x2, y2), …. (xn, yn)来描述H村的形状,这里x1 < x2 < …< xn。瞭望塔可以建造在[x1, xn]间的任意位置, 但必须满足从瞭望塔的顶端可以看到H村的任意位置。可见在不同的位置建造瞭望塔,所需要建造的高度是不同的。为了节省开支,dadzhi村长希望建造的塔高度尽可能小。
请你写一个程序,帮助dadzhi村长计算塔的最小高度。
输入输出格式
输入格式:
输入文件tower.in第一行包含一个整数n,表示轮廓折线的节点数目。接下来第一行n个整数, 为x1 ~ xn. 第三行n个整数,为y1 ~ yn。
输出格式:
输出文件tower.out仅包含一个实数,为塔的最小高度,精确到小数点后三位。
输入输出样例
说明
对于60%的数据, N ≤ 60;
对于100%的数据, N ≤ 300,输入坐标绝对值不超过106,注意考虑实数误差带来的问题
这题分两步。第一步就是求出满足条件的半平面,这半部分就是"水平可见直线"那题。
第二部就是计算答案。可以证明瞭望塔的横坐标一定在半平面或地面的拐点处,因为中间部分一定没有其中一端优秀。
所以对半平面和地面的拐点分别拎出来讨论一下就好了。
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<cmath>
- using namespace std;
- struct Line
- {
- double k,b;
- }line[],sta[];
- int n,top;
- double x[],y[],inf=1e8,eps=1e-,ans=2e12;
- int dcmp(double X)
- {
- if (X>eps) return ;
- if (X<-eps) return -;
- return ;
- }
- double getx(Line a,Line b)
- {
- return ((b.b-a.b)/(a.k-b.k));
- }
- double gety(double X)
- {int i;
- for (i=;i<=n;i++)
- {
- if (x[i+]>=X) break;
- }
- if (i==n+) return -inf;
- double k=(y[i+]-y[i])/(x[i+]-x[i]),b=y[i]-k*x[i];
- return X*k+b;
- }
- bool cmp(Line a,Line b)
- {
- if (dcmp(a.k-b.k)==)
- return a.b<b.b;
- return a.k<b.k;
- }
- int main()
- {
- int i,j;
- double maxx;
- cin>>n;
- for (i=;i<=n;i++)
- scanf("%lf",&x[i]);
- for (i=;i<=n;i++)
- scanf("%lf",&y[i]);
- for (i=;i<=n-;i++)
- {
- line[i].k=(y[i+]-y[i])/(x[i+]-x[i]);
- line[i].b=y[i]-line[i].k*x[i];
- }
- n--;
- sort(line+,line+n+,cmp);
- line[n+].k=inf;
- sta[]=line[];sta[]=line[];
- top=;
- for (i=;i<=n;i++)
- {
- if (dcmp(line[i].k-line[i+].k)==)
- continue;
- while (top>&&getx(line[i],sta[top-])<=getx(sta[top],sta[top-])) top--;
- top++;
- sta[top]=line[i];
- }
- for (i=;i<top;i++)
- {
- double X=getx(sta[i],sta[i+]);
- double Y=sta[i].k*X+sta[i].b;
- if (dcmp(Y-gety(X))>=)
- ans=min(ans,Y-gety(X));
- }
- for (i=;i<=n+;i++)
- {
- maxx=;
- for (j=;j<=top;j++)
- {
- maxx=max(maxx,x[i]*sta[j].k+sta[j].b);
- }
- if (dcmp(maxx-y[i])>=)
- ans=min(ans,maxx-y[i]);
- }
- printf("%.3lf\n",ans);
- }
本题可以使用三分法
将点按横坐标排好序后
对于任意相意两个点连成的线段,瞭望塔的高度 是单峰函数,而且是下凸函数
感性理解单峰就是
瞭望塔建的靠左,为了能看到右边的,要高一点
瞭望塔建的靠右,为了能看到左边的,要高一点
所以 枚举所有线段,三分线段上建造瞭望塔的位置,所有线段上的瞭望塔高度取最小
- #include<iostream>
- #include<cstdio>
- #include<cstring>
- #include<algorithm>
- #include<cmath>
- using namespace std;
- struct Node
- {
- double k,b;
- int pd;
- }L[];
- int n;
- double px[],py[],eps=1e-,ans;
- int dcmp(double x)
- {
- if (x>eps) return ;
- if (x<-eps) return -;
- return ;
- }
- double cal(double X,double Y)
- {int i;
- double tmp=;
- for (i=;i<n;i++)
- {
- if (L[i].pd==) continue;
- tmp=max(tmp,L[i].k*X+L[i].b-Y);
- }
- return tmp;
- }
- int main()
- {int i;
- cin>>n;
- for (i=;i<=n;i++)
- scanf("%lf",&px[i]);
- for (i=;i<=n;i++)
- scanf("%lf",&py[i]);
- for (i=;i<n;i++)
- {
- if (dcmp(px[i]-px[i+])==) continue;
- L[i].k=(py[i]-py[i+])/(px[i]-px[i+]);
- L[i].b=py[i]-L[i].k*px[i];
- L[i].pd=;
- }
- ans=2e15;
- for (i=;i<n;i++)
- {
- if (L[i].pd==) continue;
- int T=;
- double l=px[i],r=px[i+];
- double mid1,mid2;
- while (T--)
- {
- mid1=(r-l)/+l,mid2=r-(r-l)/;
- if (dcmp(cal(mid1,mid1*L[i].k+L[i].b)-cal(mid2,mid2*L[i].k+L[i].b))>=) l=mid1;
- else r=mid2;
- }
- ans=min(ans,cal(mid1,mid1*L[i].k+L[i].b));
- }
- printf("%.3lf\n",ans);
- }
[ZJOI2008]瞭望塔的更多相关文章
- 【BZOJ 1038】 1038: [ZJOI2008]瞭望塔
1038: [ZJOI2008]瞭望塔 Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 ...
- 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]瞭望塔
半平面交. 半平面指的就是一条直线的左面(也不知道对不对) 半平面交就是指很多半平面的公共部分. 这道题的解一定在各条直线的半平面交中. 而且瞭望塔只可能在各个点或者半平面交折线的拐点处. 求出半平面 ...
- 1038: [ZJOI2008]瞭望塔 - BZOJ
Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1, ...
- bzoj1038: [ZJOI2008]瞭望塔
Description 致力于建设全国示范和谐小村庄的H村村长dadzhi,决定在村中建立一个瞭望塔,以此加强村中的治安.我们将H村抽象为一维的轮廓.如下图所示 我们可以用一条山的上方轮廓折线(x1, ...
- 【BZOJ 1038】[ZJOI2008]瞭望塔
[题目链接]:http://www.lydsy.com/JudgeOnline/problem.php?id=1038 [题意] [题解] 可以看到所有村子的瞭望塔所在的位置只会是在相邻两个村子所代表 ...
- [日常摸鱼]bzoj1038 [ZJOI2008]瞭望塔-模拟退火/几何
题意:给一条平面内$n$个点的折线,要求在折线上搞一个高度$h$的瞭望塔,能够看见折线上所有的点,求$h$的最小值($n \leq 300$) updata2018.1.21 正解半平面交在另一篇里面 ...
随机推荐
- android 与 服务器通信
android 与 服务器通信 服务端代码: (1)control 层 /** * 用户登录 * @return */ @RequestMapping(value = "/login&quo ...
- I know 项目Alpha冲刺随笔集
Alpha冲刺 Day 1 Alpha冲刺 Day 2 Alpha冲刺 Day 3 Alpha冲刺 Day 4 Alpha冲刺 Day 5 Alpha冲刺 Day 6 Alpha冲刺 Day 7 Al ...
- 20162308 实验二《Java面向对象程序设计》实验报告
20162308 实验二<Java面向对象程序设计>实验报告 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉S.O.L.I.D原则 ...
- Beta冲刺-用户测试报告
一.项目概述 1.1项目名称 高校学生征信系统 1.2项目简介 此项目基于SSH框架,力图为学生提供征信服务和信用相关的借款和申请活动.其中以信用统计和管理为主,信用使用为辅,构建出一个集信用收集和使 ...
- 20162323周楠《Java程序设计与数据结构》第五周总结
20162323周楠 2016-2017-2 <程序设计与数据结构>第五周学习总结 教材学习内容总结 1.面向对象软件设计的基本部分是确定程序中应该创建哪些类: 2.面向对象程序设计的核心 ...
- Scrum 冲刺 第六日
Scrum 冲刺 第六日 目录 要求 项目链接 燃尽图 问题 今日任务 明日计划 成员贡献量 要求 各个成员今日完成的任务(如果完成的任务为开发或测试任务,需给出对应的Github代码签入记录截图:如 ...
- js 选择图片生成base64数据
<!doctype html> <html> <head> <meta charset="utf-8"> <meta http ...
- NOIP2012 提高组 Day 2
http://www.cogs.pro/cogs/page/page.php?aid=16 期望得分:100+100+0=0 实际得分:100+20+0=120 T2线段树标记下传出错 T1 同余方程 ...
- SQL SERVER 游标的使用
首先,关于什么是游标大家可以看看这篇文章,介绍得非常详细!! SQL Server基础之游标 下面是我自己的应用场景-- 有个需求,需要把数据库表里面某一个字段的值设为随机不重复的值. 表是这样的: ...
- Mego开发文档 - 基础查询
基础查询 Mego 使用语言集成查询(LINQ)从数据库查询数据.LINQ允许您使用C#(或其他.NET语言)根据派生的上下文和实体类编写强类型查询.将LINQ查询的表示传递给数据库提供者,翻译为数据 ...