//    hdu5033 Building 单调队列
//
// 题目大意:
//
// n栋大楼,有一个高度h和位置x。如今有一个人高度为0,有q个询问
// 每一个询问有一个位置x,求在位置x能看到天空的最大的角度。
//
// 解题思路:
//
// 首先得想到将q个询问的位置作为一栋大楼放在整个大楼中考虑。这样
// 问题就比較一致,也比較easy处理啦。
//
// 想象一下,每次从左往右走,对于当前位置的左半边的90度内,看天的角度是
// 逐渐减小的,这样。假设当前位置的左边比当前位置要低,那么当前位置就挡住了
// 之前的更矮的。也就是说之后的位置是不可能看到比当前更矮的大楼了,这样。就可
// 以看成是一个单调的序列。序列中元素高度单调递减,即所谓的单调队列。 但仅仅仅仅是
// 这样是不够的。也会存在比当前元素(设为h)高设为h1,在队列中h1前面的元素是h2,尽管
// h1是比h大,可是假设顺着h1的高度看过去。会被h2挡住。这时h1是没有作用的。也要将
// 这个元素从队列中移除。
//
// 当遇到的大楼要查询的位置的时候,此时队列最后的一个元素并不一定是最优的值,由于
// 这种值可能是不合法的。比方上面的h1会被h2挡住。并不会看到天空。 照样移除这种元素
// 最后,队列的最后一个元素就是解。
//
// 右边的问题全然能够转化为左边的问题,仅仅是从右往左处理而已。 //
//
// 感悟:
//
// 这道题是14年北京区的网赛的一道题目,当时的我尽管看懂了题目的意思。可是真的全然不会做。
// 直到如今伟大的MW大咖,说是单调队列能够做,我就做了。可是卡了一天半,还是想不出来详细怎么解
// 首先将询问的位置当作大楼这一点我想到了,维持高度递减的单调队列我想到了,就是最后一种情况没有
// 想到,更不知道要怎么处理,在伟大的MW大咖的敦敦教诲还有耐心的提示下。最终最终想到了解决的办法
// 不easy啊不easy。在此真诚感谢MW大咖~
//
// 过程无疑会有非常多的疑惑,一个地方不慎。满盘皆输,找到一处的错误。心里十分的欣喜,特别是在ac
// 之后。那种心情。实在是难以描写叙述。感觉到自己的付出,真的是有回报。曾经不懂的东西,自己认真学
// 总会有收获。哪怕收获是那么一点点,微不足道,但收获就是收获,没有这个能让人更加欣喜啦,痛苦并快乐着
// 十分的享受。还是那句话,继续练吧~~~ #include <cstdio>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <cstring>
using namespace std; const int MAX_N = 2e5 + 9; const double PI = acos(-1.0);
int n,q;
double deqh[MAX_N];
double deqx[MAX_N];
double angle[MAX_N]; struct node {
double pos;
double h;
int id; node(){ } node(double pos,double h,int id):pos(pos),h(h),id(id){ }
}; node sky[MAX_N]; bool cmp(node a,node b){
return a.pos < b.pos;
} void input(){
scanf("%d",&n);
double x,h;
for (int i = 1;i <= n;i++){
scanf("%lf%lf",&x,&h);
sky[i] = node(x,h,0);
}
scanf("%d",&q); for (int i = 1;i <= q;i++){
scanf("%lf",&x);
sky[i+n] = node(x,0.0,i);
angle[i] = 0.0;
} n += q; sort(sky+1,sky+n+1,cmp);
} double getk(double a,double b){
return fabs(a/b);
} void getleft(){
int head,tail;
head = tail = 0;
for (int i=1;i<=n;i++){
if (sky[i].id){
while(head + 1 < tail){
double k1 = getk(deqh[tail-1],deqx[tail-1]-sky[i].pos);
double k2 = getk(deqh[tail-2],deqx[tail-2]-sky[i].pos);
if (k1 <= k2)
tail--;
else break;
}
angle[sky[i].id] += atan(deqh[tail-1]/fabs(deqx[tail-1]-sky[i].pos));
}else { while(head < tail && deqh[tail-1] < sky[i].h)
tail--; while(head + 1 < tail){
double k1 = getk(deqh[tail-1]-sky[i].h,deqx[tail-1]-sky[i].pos);
double k2 = getk(deqh[tail-2]-sky[i].h,deqx[tail-2]-sky[i].pos);
if (k1 <= k2)
tail--;
else
break;
}
deqh[tail] = sky[i].h;
deqx[tail++] = sky[i].pos;
}
}
} void getright(){
int head,tail;
head = tail = 0;
for (int i = n;i >= 1;i--){
if (sky[i].id){
while(head + 1 < tail){
double k1 = getk(deqh[tail-1],deqx[tail-1]-sky[i].pos);
double k2 = getk(deqh[tail-2],deqx[tail-2]-sky[i].pos);
if (k1 <= k2)
tail--;
else
break;
} angle[sky[i].id] += atan(deqh[tail-1]/fabs(deqx[tail-1]-sky[i].pos)); }else {
while(head < tail && deqh[tail-1] < sky[i].h)
tail--; while(head + 1 < tail){ double k1 = getk(deqh[tail-1]-sky[i].h,deqx[tail-1] - sky[i].pos);
double k2 = getk(deqh[tail-2]-sky[i].h,deqx[tail-2] - sky[i].pos); if (k1 <= k2){
tail--;
}else
break; }
deqh[tail] = sky[i].h;
deqx[tail++] = sky[i].pos;
}
}
} void solve(){
getleft();
getright();
for (int i=1;i<=q;i++){
printf("%.10lf\n",(PI - angle[i]) * 180.0 / PI);
}
} int main(){
int t;
//freopen("1.txt","r",stdin);
scanf("%d",&t);
int kase = 1;
while(t--){
input();
printf("Case #%d:\n",kase++);
solve();
}
}

hdu5033 Building 单调队列的更多相关文章

  1. HDU5033 building 单调栈+计算几何

    正解:单调栈 解题报告: 哇生气辽QAQ本来打了半天feel good都快调出来了然后说换题了QAQ(所以可能那题的代码会过一阵子再放上来了QAQ 不过还是大爆手速打了一通拿到首杀了嘻嘻 美滋滋辽 然 ...

  2. HDU5033 Building(单调栈)

    题意是说在水平轴上有很多建筑物(没有宽度),知道每个建筑物的位置与高度.有m个查询,每次查询位置x所能看到的天空的角度. 方法是将建筑与查询一起排序,从左往右计算一遍,如果是建筑物,则比较最后两个(当 ...

  3. hdu5033 Building (单调栈+)

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

  4. [hdu5033]单调队列

    题意:x轴上有n棵树,询问你站在某个点的视角.从左至右,单调队列(类似凸包)维护下.我强迫症地写了个模板QAQ #include <iostream> #include <cstdi ...

  5. BestCoder Round #89 B题---Fxx and game(单调队列)

    题目链接 http://acm.hdu.edu.cn/showproblem.php?pid=5945     问题描述 输入描述 输出描述 输入样例 输出样例 题意:中文题,不再赘述: 思路:  B ...

  6. 单调队列 && 斜率优化dp 专题

    首先得讲一下单调队列,顾名思义,单调队列就是队列中的每个元素具有单调性,如果是单调递增队列,那么每个元素都是单调递增的,反正,亦然. 那么如何对单调队列进行操作呢? 是这样的:对于单调队列而言,队首和 ...

  7. FZU 1914 单调队列

    题目链接:http://acm.fzu.edu.cn/problem.php?pid=1914 题意: 给出一个数列,如果它的前i(1<=i<=n)项和都是正的,那么这个数列是正的,问这个 ...

  8. BZOJ 1047 二维单调队列

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1047 题意:见中文题面 思路:该题是求二维的子矩阵的最大值与最小值的差值尽量小.所以可以考 ...

  9. 【BZOJ3314】 [Usaco2013 Nov]Crowded Cows 单调队列

    第一次写单调队列太垃圾... 左右各扫一遍即可. #include <iostream> #include <cstdio> #include <cstring> ...

随机推荐

  1. MongoDB初探系列之四:MongoDB与Java共舞

    因为版本号不同,可能API也有所不同.本次学习用的是3.0版本号. 1.使用的mongodb的jdbc驱动版本号为:mongo-java-driver-3.0.0.jar 2.本节仅仅是简介JDBC操 ...

  2. 编写函数int count_number_string(char str[])和函数int maxnum_string(char str[])

    题目如图: 这里不再赘述 代码: //字符串中统计与查询 //杨鑫 #include <stdio.h> #include <stdlib.h> #include <st ...

  3. windows 下载安装github

    参考链接:http://download.csdn.net/download/devsplash/9683971

  4. 杂项-电信:TL9000

    ylbtech-杂项-电信:TL9000 TL9000是电信业质量体系要求(书1)与质量体系法则(书2)的指南, 它包括ISO9001的所有要求,以及硬件.软件, 服务方面行业的特别要求. 这些新增要 ...

  5. Spark RDD概念学习系列之如何创建RDD

    不多说,直接上干货! 创建RDD 方式一:从集合创建RDD (1)makeRDD (2)Parallelize 注意:makeRDD可以指定每个分区perferredLocations参数,而para ...

  6. [转]C#事件-使用事件需要的步骤

    事件是C#中另一高级概念,使用方法和委托相关.奥运会参加百米的田径运动员听到枪声,比赛立即进行.其中枪声是事件,而运动员比赛就是这个事件发生后的动作.不参加该项比赛的人对枪声没有反应. 从程序员的角度 ...

  7. 理解Cookie与Session

    HTTP本身是无状态的. 这符合HTTP协议设计的目的.客户端只是简单地向服务器请求某种资源.两者都没有必须记录彼此过去的行为,每一次请求之间都是独立的. 为了保存状态.在客户端使用Cookie,在S ...

  8. 使用DWR实现JS调用服务端Java代码

    DWR简介 DWR全称Direct Web Remoting,是一款非常优秀的远程过程调用(Remote Procedure Call)框架,通过浏览器提供的Ajax引擎实现在前端页面的JS代码中调用 ...

  9. GCC中的弱符号与强符号

    GCC中的弱符号与强符号 我们经常在编程中碰到一种情况叫符号重复定义.多个目标文件中含有相同名字全局符号的定义,那么这些目标文件链接的时候将会出现符号重复定义的错误.比如我们在目标文件A和目标文件B都 ...

  10. Pyhton学习——Day38

    #CSS:Cascading Style Sheets——层叠样式表# CSS的四种引入方式# 行内式是在标记的style属性中设定CSS样式.这种方式没有体现出CSS的优势,不推荐使用.###### ...