题目链接

题意:n个建筑物,Q条询问,问所在的位置,看到天空的角度是多少,每条询问的位置左右必定是有建筑物的。

思路 : 维护一个单调栈,将所有的建筑物和所有的人都放到一起开始算就行,每加入一个人,就维护栈里的建筑物的高度,也就是说这个人所能够看到的建筑物时在栈里的,但是这个人看不到的就删掉,例如下图,中间三个点可以删掉了,因为角度问题中间三个是看不到的,所以不会影响最终求得角度

还有一种情况,就是下述的情况,不停的维护单调栈,人站在不同的地方角度也是不一样的。

维护的是相邻两建筑顶(xi,hi)的连线的斜率的绝对值上升 的单调栈。

从左往右一遍,右往左一遍。

下图是代码中judge函数的图,要判断是否建筑物被另一建筑物遮挡。

 #include <stdio.h>
#include <string.h>
#include <math.h>
#include <iostream>
#include <stack>
#include <algorithm>
#define PI acos(-1.0)
using namespace std ; struct node
{
int pos ;
int height ;
bool operator <(const node &a)const
{
return pos < a.pos ;
}
} p[],stk[];
double sh[] ;
int T,n,q; int judge(node &a,node &b,node c){//判断在c处的视野中,a建筑物是否能够在c处没有被b建筑物挡住
if(c.height <= ) c.height = ;
return (long long)(a.height-c.height)*(c.pos-b.pos) >= (long long)(b.height-c.height)*(c.pos-a.pos) ;
} double angle(node a,node b)//求a建筑物与b处所成角的大小
{
return atan((double)(b.pos-a.pos)/(double)(a.height)) ;
}
void solve()
{
int top = ;
for(int i = ; i < n+q ; i ++){
if(p[i].height <= ){//是人的地方
while(top >= && judge(stk[top-],stk[top-],p[i])) top -- ;//如果top-1挡不住top-2的话,说明top-1在角度贡献上没什么用
sh[-p[i].height] += angle(stk[top-],p[i]) ;
}
else
{
while(top && stk[top-].height <= p[i].height) top-- ;//如果栈顶元素没有新的这个高,那么肯定会被挡到,所以没有用删掉
while(top >= && judge(stk[top-],stk[top-],p[i])) top--;//把这三个建筑物的最高点相连,若是凹的,中间那个肯定会被挡到,删掉
stk[top++] = p[i] ;
}
}
}
int main()
{
scanf("%d",&T) ;
int casee = ;
while(T--)
{
scanf("%d",&n) ;
for(int i = ; i < n ; i++)
{
scanf("%d %d",&p[i].pos,&p[i].height) ;
}
scanf("%d",&q) ;
for(int i = ; i < q ; i++)
{
scanf("%d",&p[i+n].pos) ;
p[i+n].height = -i ;//输出方便
}
memset(sh,,sizeof(sh)) ;
sort(p,p+n+q) ;
solve() ;
reverse(p,p+n+q) ;
for(int i = ; i < n+q ; i++)//把后边的全部都移到前边去,与上边的统一,方便调用函数
p[i].pos = -p[i].pos ;
solve() ;
printf("Case #%d:\n",casee++) ;
for(int i = ; i < q ; i++){
printf("%.10lf\n",sh[i]*/PI) ;//角度与弧度的转化
}
}
return ;
}

HDU 5033 Building (维护单调栈)的更多相关文章

  1. hdu - 5033 - Building(单调栈)

    题意:N 幢楼排成一列(1<=N<=10^5),各楼有横坐标 xi(1<=xi<=10^7) 以及高度 hi(1<=hi<=10^7),在各楼之间的Q个位置(1&l ...

  2. HDU 5033 Building --离线+单调栈

    题意:给一些建筑物,x表示横坐标,h表示高度,然后查询某些坐标x,问从该点看向天空的最大张角是多大. 解法:离线操作,读入所有数据,然后按x升序排序,对每一个查询的x,先从左到右,依次添加x坐标小于x ...

  3. hdu 5033 buiding(单调栈)

    hdu 5033 buiding(单调栈) 某年某月某天,马特去了一个小镇.这个小镇如此狭窄,以至于他可以把小镇当作一个枢纽.在镇上有一些摩天大楼,其中一栋位于xi,高度为hi.所有的摩天大楼位于不同 ...

  4. HDU 5033 Building(单调栈)

    HDU 5033 Building(单调栈) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5033 Description Once upon a ti ...

  5. HDU 5033 Building(北京网络赛B题) 单调栈 找规律

    做了三天,,,终于a了... 11724203 2014-09-25 09:37:44 Accepted 5033 781MS 7400K 4751 B G++ czy Building Time L ...

  6. hdu5033 Building (单调栈+)

    http://acm.hdu.edu.cn/showproblem.php?pid=5033 2014 ACM/ICPC Asia Regional Beijing Online B 1002 Bui ...

  7. 【洛谷5294】[HNOI2019] 序列(主席树维护单调栈+二分)

    点此看题面 大致题意: 给你一个长度为\(n\)的序列\(A\),每次询问修改一个元素(只对当前询问有效),然后让你找到一个不下降序列\(B\),使得这两个序列相应位置之差的平方和最小,并输出这个最小 ...

  8. [CSP-S模拟测试]:陶陶摘苹果(线段树维护单调栈)

    题目传送门(内部题116) 输入格式 第一行两个整数$n,m$,如题 第二行有$n$个整数表示$h_1-h_n(1\leqslant h_i\leqslant 10^9)$ 接下来有$m$行,每行两个 ...

  9. hdu 5033 Building (单调栈 或 暴力枚举 )

    Description Once upon a time Matt went to a small town. The town was so small and narrow that he can ...

随机推荐

  1. enumerate 枚举

  2. Mybatis中对于标签的配置可能不会出现自动提示解决方案

    解决办法:引入mybatis-3-config.dtd 文件 Window-preferences-搜索xml-xml catalog <!DOCTYPE configuration PUBLI ...

  3. kafka集群下线broker节点实践方法(broker topic 迁移)

    [root@es03 ~]# cd /usr/hdp//kafka/bin [root@es03 kafka]# cd bi -bash: cd: bi: No such file or direct ...

  4. ACM学习历程—SNNUOJ1215 矩阵2(二分 && dfs)

    http://219.244.176.199/JudgeOnline/problem.php?id=1215 这是这次微软和百度实习面试的一道题,题目大意就是:有一个n*m的矩阵,已知它每一行都是不严 ...

  5. shell split函数的使用

    #!/bin/awk -f BEGIN{FS=","} {split($1,name," "); for (i in name) print name[i] }

  6. VisualGDB系列8:使用VS创建CMake Linux项目

    根据VisualGDB官网(https://visualgdb.com)的帮助文档大致翻译而成.主要是作为个人学习记录.有错误的地方,Robin欢迎大家指正. 本文介绍如何使用VS来创建.构建.调试一 ...

  7. java代码异常普通的====

    总结:对于各种流类, package com.da; //包括运行异常,和非运行异常 import java.io.*; public class ryl { public static void m ...

  8. 关于mybatis中基本类型条件判断问题

    零:sql动态语句中经常会有根据数据库某个字段状态进行判断的 如:status=0为未激活,status=1为激活的,那搜索未激活时: <if test="model.activeSt ...

  9. 创建,查看,删除pool,查看,修改pool参数命令总结

    标签(空格分隔): ceph,ceph运维,pool 1. 创建pool命令: ceph的pool有两种类型,一种是副本池,一种是ec池,创建时也有所区别 1.1 创建副本池: $ sudo ceph ...

  10. C++模板的一些巧妙功能

    判断类中是否有指定名称的函数: #include<utility> #define HAS_MEMBER(member)\ template<typename T,typename. ...