hdu5033 Building (单调栈+)
http://acm.hdu.edu.cn/showproblem.php?pid=5033
2014 ACM/ICPC Asia Regional Beijing Online B 1002
BuildingTime Limit: 10000/5000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Problem Description
Once upon a time Matt went to a small town. The town was so small and narrow that he can regard the town as a pivot. There were some skyscrapers in the town, each located at position xi with its height hi. All skyscrapers located in different place. The skyscrapers had no width, to make it simple. As the skyscrapers were so high, Matt could hardly see the sky.Given the position Matt was at, he wanted to know how large the angle range was where he could see the sky. Assume that Matt's height is 0. It's guaranteed that for each query, there is at least one building on both Matt's left and right, and no building locate at his position.
Input
The first line of the input contains an integer T, denoting the number of testcases. Then T test cases follow.
Each test case begins with a number N(1<=N<=10^5), the number of buildings. In the following N lines, each line contains two numbers, xi(1<=xi<=10^7) and hi(1<=hi<=10^7). After that, there's a number Q(1<=Q<=10^5) for the number of queries. In the following Q lines, each line contains one number qi, which is the position Matt was at. Output
For each test case, first output one line "Case #x:", where x is the case number (starting from 1).
Then for each query, you should output the angle range Matt could see the sky in degrees. The relative error of the answer should be no more than 10^(-4). Sample Input
3
3 1 2 2 1 5 1 1 4 3 1 3 2 2 5 1 1 4 3 1 4 2 3 5 1 1 4 Sample Output
Case #1:
101.3099324740 Case #2: 90.0000000000 Case #3: 78.6900675260 |
题意:
城市看做二维平面,建筑看做x轴上某个位置为端点的竖着的线段,(xi,hi)表示在x轴xi位置有个高为hi的建筑(线段)。有多次询问,每次问人在某个平地上(x,0)能看到天空的角度。
题解:
维护 相邻两建筑顶(xi,hi)的连线的斜率的绝对值上升 的单调栈。
先把建筑和queries的点全部弄到一起,按xi排个序。然后从左到右来一波得出在某个空地往左看看到最高的是哪个建筑,再反过来来一波。
先按从左到右的情况来说:
维护单调栈,栈里存的是之后的空地可能看到的建筑,容易知这是递减的单调栈。
再思考,如果:
则只用存两边的点,中间那3个肯定看不到了。
如果:
则都要存,因为往右走的时候走着走着,右边第二个就比右边第一个高了,走着走着右边第三个又比右边第二个高了……(这时pop掉栈顶
可见我们存的是相邻两建筑顶(xi,hi)的连线的斜率的绝对值上升 的单调栈。
每看到一个空地,把栈首的不够高的都pop到,只留下那个能看到的最高的,然后把这个建筑加入结果记录中。(记录从这个空地往左看看到的最高的是哪个建筑)
反过来再来一遍。
最后再对询问搞一搞,就完啦。
(我写的时候以为xi hi是整数,所以里面都是用整数搞的,后来看Clarify才发现是实数,改了一波)
代码:
//#pragma comment(linker, "/STACK:102400000,102400000")
#include<cstdio>
#include<cmath>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<map>
#include<set>
#include<stack>
#include<queue>
using namespace std;
#define ll long long
#define usll unsigned ll
#define mz(array) memset(array, 0, sizeof(array))
#define mf1(array) memset(array, -1, sizeof(array))
#define minf(array) memset(array, 0x3f, sizeof(array))
#define REP(i,n) for(i=0;i<(n);i++)
#define FOR(i,x,n) for(i=(x);i<=(n);i++)
#define RD(x) scanf("%d",&x)
#define RD2(x,y) scanf("%d%d",&x,&y)
#define RD3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define WN(x) printf("%d\n",x);
#define RE freopen("D.in","r",stdin)
#define WE freopen("huzhi.txt","w",stdout)
#define mp make_pair
#define pb push_back
const double pi=acos(-1.0);
const double eps=1e-; const int maxn=;
const int maxm=*maxn; struct Bd {
double x,h;
int q;
} a[maxm];
int n,Q;
double q[maxn]; bool cmp(Bd x,Bd y) {
return x.x<y.x; } int L[maxn],R[maxn];///对应q[] int b[maxn];///a[b[]].h 降序单调队列,并且相邻斜率(Δh/Δx)依次更斜
int r; void mypb(int x) {
while(r> && a[b[r-]].h <= a[x].h)r--;///保持降序
///要保持:a[x]与a[b[r-1]]的斜率(负数) 小于 a[b[r-1]]与a[b[r-2]]的
///(a[x].h - a[b[r-1]].h)/(a[x].x - a[b[r-1]].x) < (a[b[r-1]].h - a[b[r-2]].h)/(a[b[r-1]].x - a[b[r-2]].x)
///(a[x].h - a[b[r-1]].h)*(a[b[r-1]].x - a[b[r-2]].x)<(a[b[r-1]].h - a[b[r-2]].h)*(a[x].x - a[b[r-1]].x)
///实数
while(r> && ((a[x].h - a[b[r-]].h))*(fabs(a[b[r-]].x - a[b[r-]].x))>=((a[b[r-]].h - a[b[r-]].h))*(fabs(a[x].x - a[b[r-]].x)))
r--;///保持斜率
b[r++]=x;
//printf("PUSH b[%d]=%d\t%d %d\tr=%d\n",r-1,x,a[x].x,a[x].h,r);
} void farm() {
int i;
///一共有n+Q个元素,在1~n+Q里
int m=n+Q;
sort(a+,a+m+,cmp);
a[].x=;
a[].h=;
r=;
b[]=;
FOR(i,,m) {
//printf("a[%d].x=%d , .h=%d\n",i,a[i].x,a[i].h);
if(a[i].h>0.0)mypb(i);
else {
///从队尾,找到对于x最斜的那个
///当 a[b[r-1]].h/(a[i].x - a[b[r-1]].x) <= a[b[r-2]].h/(a[i].x - a[b[r-2]].x)时pop
/// a[b[r-1]].h*(a[i].x - a[b[r-2]].x) <= a[b[r-2]].h*(a[i].x - a[b[r-1]].x)
///实数
while(r> && (a[b[r-]].h)*(fabs(a[i].x - a[b[r-]].x)) <= (a[b[r-]].h)*(fabs(a[i].x - a[b[r-]].x))) {
//printf("POP %d %d\n",a[b[r-1]].x,a[b[r-1]].h);
r--;
}
//printf("!r=%d!\n",r);
L[a[i].q]=b[r-];
//printf("L[%d]=b[%d]=%d\tr=%d\n",-a[i].h,r-1,b[r-1],r);
}
} ///右边开始
a[m+].x=a[m].x+;
a[m+].h=;
r=;
b[]=m+;
for(i=m; i>=; i--) {
//printf("a[%d].x=%d , .h=%d\n",i,a[i].x,a[i].h);
if(a[i].h>)mypb(i);
else {
///从队尾,找到对于x最斜的那个
///当 a[b[r-1]].h/(a[i].x - a[b[r-1]].x) <= a[b[r-2]].h/(a[i].x - a[b[r-2]].x)时pop
/// a[b[r-1]].h*(a[i].x - a[b[r-2]].x) <= a[b[r-2]].h*(a[i].x - a[b[r-1]].x)
///可能超int
while(r> && (a[b[r-]].h)*(fabs(a[i].x - a[b[r-]].x)) <= (a[b[r-]].h)*(fabs(a[i].x - a[b[r-]].x))) {
//printf("POP %d %d\n",a[b[r-1]].x,a[b[r-1]].h);
r--;
}
R[a[i].q]=b[r-];
//printf("L[%d]=%d\n",-a[i].h,b[r-1]);
}
}
} double gank(int x) {
Bd lb=a[L[x]];
Bd rb=a[R[x]];
//printf("%d %d %d %d\n",lb.x,lb.h,rb.x,rb.h);
double lj=atan2((lb.h),(fabs(lb.x-q[x])));
double rj=atan2((rb.h),(fabs(rb.x-q[x])));
return (pi-lj-rj)/pi*180.0;
} int main() {
int T,cas=;
int i;
RD(T);
while(T--) {
RD(n);
FOR(i,,n)scanf("%lf%lf",&a[i].x,&a[i].h);
RD(Q);
FOR(i,,Q) {
scanf("%lf",&q[i]);
a[n+i].x=q[i];
a[n+i].h=0.0;
a[n+i].q=i;///这是第i个请求
}
farm();
printf("Case #%d:\n",cas++);
FOR(i,,Q) {
printf("%.10lf\n",gank(i));
}
}
return ;
}
hdu5033 Building (单调栈+)的更多相关文章
- HDU5033 building 单调栈+计算几何
正解:单调栈 解题报告: 哇生气辽QAQ本来打了半天feel good都快调出来了然后说换题了QAQ(所以可能那题的代码会过一阵子再放上来了QAQ 不过还是大爆手速打了一通拿到首杀了嘻嘻 美滋滋辽 然 ...
- HDU5033 Building(单调栈)
题意是说在水平轴上有很多建筑物(没有宽度),知道每个建筑物的位置与高度.有m个查询,每次查询位置x所能看到的天空的角度. 方法是将建筑与查询一起排序,从左往右计算一遍,如果是建筑物,则比较最后两个(当 ...
- HDU 5033 Building(单调栈)
HDU 5033 Building(单调栈) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5033 Description Once upon a ti ...
- hdu5033 Building 单调队列
// hdu5033 Building 单调队列 // // 题目大意: // // n栋大楼,有一个高度h和位置x.如今有一个人高度为0,有q个询问 // 每一个询问有一个位置x,求在位置x能看到天 ...
- hdu 5033 Building (单调栈 或 暴力枚举 )
Description Once upon a time Matt went to a small town. The town was so small and narrow that he can ...
- HDU - 5033 Building (单调栈+倍增)
题意:有一排建筑,每座建筑有一定的高度,宽度可以忽略,求在某点的平地上能看到天空的最大角度. 网上的做法基本都是离线的...其实这道题是可以在线做的. 对于向右能看到的最大角度,从右往左倍增维护每个时 ...
- HDU 5033 Building(单调栈维护凸包)
盗张图:来自http://blog.csdn.net/xuechelingxiao/article/details/39494433 题目大意:有一排建筑物坐落在一条直线上,每个建筑物都有一定的高度, ...
- HDU 5033 Building(北京网络赛B题) 单调栈 找规律
做了三天,,,终于a了... 11724203 2014-09-25 09:37:44 Accepted 5033 781MS 7400K 4751 B G++ czy Building Time L ...
- HDU 5033 Building (维护单调栈)
题目链接 题意:n个建筑物,Q条询问,问所在的位置,看到天空的角度是多少,每条询问的位置左右必定是有建筑物的. 思路 : 维护一个单调栈,将所有的建筑物和所有的人都放到一起开始算就行,每加入一个人,就 ...
随机推荐
- 【UOJ#33】【UR#2】树上GCD 有根树点分治 + 容斥原理 + 分块
#33. [UR #2]树上GCD 有一棵$n$个结点的有根树$T$.结点编号为$1…n$,其中根结点为$1$. 树上每条边的长度为$1$.我们用$d(x,y)$表示结点$x,y$在树上的距离,$LC ...
- 【BZOJ-1017】魔兽地图DotR 树形DP + 背包
1017: [JSOI2008]魔兽地图DotR Time Limit: 30 Sec Memory Limit: 162 MBSubmit: 1566 Solved: 705[Submit][S ...
- Jenkins实现生产环境部署文件的回滚操作(Windows)
由于dotnet项目的生产环境环境部署工具比较少,所以我使用jenkins作为生产环境的自动化部署工具. 既然有回滚操作,那么就会有部署操作:要实现回滚,先要实现部署的操作,我在jenkins搭建了一 ...
- Uva1398 Meteor
扫描线法. 将流星出现在相机里的时间转化成线段,离散化端点后,扫描何时出现的流星最多.注意边界的不算,所以要先减右端点再加左端点 /*By SilverN*/ #include<iostream ...
- Discuz! X upgrade/converter GETSHELL Vulnerability Via /convert/include/global.func.php Inject Special Symbol Into /convert/data/config.inc.php
目录 . 漏洞描述 . 漏洞触发条件 . 漏洞影响范围 . 漏洞代码分析 . 防御方法 . 攻防思考 1. 漏洞描述 对于PHP应用来说,处于用户的输入并正确划定"数据-代码"边界 ...
- C#实体图片下载与批量下载(自动保存功能)
新工作,第一个小任务,制作一个点击下载图片的功能.并提供批量下载操作.图片是字节流的形式,存放在数据库中的. 为了避免直接从数据库中,下载失败,会在本地保存一份. 进行压缩的是SharpZip这个压缩 ...
- POJ 2823 Sliding Window + 单调队列
一.概念介绍 1. 双端队列 双端队列是一种线性表,是一种特殊的队列,遵守先进先出的原则.双端队列支持以下4种操作: (1) 从队首删除 (2) 从队尾删除 (3) 从队尾插入 (4) ...
- 2015年10月份经常使用的linux命令。
ps -ef |grep 服务名 详细的介绍可以参考此篇博客http://www.cnblogs.com/wangkangluo1/archive/2011/09/23/218593 ...
- 9.12 其他样式;JS
Display 显示block和隐藏none,不占位置Visbility 显示visible和隐藏hidden,占位置Overflow 超出范围 hidden隐藏透明圆角 Js脚本语言(JavaScr ...
- SQL Server 2012 学习笔记1
1. 新建的数据库会产生两个文件(数据文件.mdf 和日志文件.ldf) 2. 编辑表格和为表格录入数据 "Design"为设计表格,"Edit Top 200 Rows ...