//    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. sql查询语句中的乱码 -- 前面加N

    直接运行sql出出现乱码,在中文字符前加N就能够正常显示了.N的含义就是用nvarchar格式显示.

  2. 串口之CreateFile 函数具体解释

    HANDLE CreateFile( LPCTSTR lpFileName, //指向文件名称的指针 DWORD dwDesiredAccess, //訪问模式(写/读) DWORD dwShareM ...

  3. 利用flashback transaction query新特性进行事务撤销

    具备了flashback version query查询的基础,我们就可以进行基于flashback version query的恢复.这就是flashback transaction query.f ...

  4. Spark RDD概念学习系列之什么是Pair RDD

    不多说,直接上干货! 什么是Pair RDD (1)包含键值对类型的RDD被称作Pair RDD. (2)Pair RDD通常用来进行聚合计算. (3)Pair RDD通常由普通RDD做ETL转换而来 ...

  5. ThinkPHP5(目录,路径,模式设置,命名空间)

    ThinkPHP是一个快速.兼容而且简单的轻量级国产PHP开发框架 目录结构 路径: http://www.tp5.comm/index.php/admin/index/index入口文件    pu ...

  6. js获取浏览器中相关容器的高度

    网页可见区域宽: document.body.clientWidth 网页可见区域高: document.body.clientHeight 网页可见区域宽: document.body.offset ...

  7. 设置cookie,删除cookie,读取cookie

    1.首先来说下cookie的作用 我们在浏览器中,经常涉及到数据的交换,比如你登录邮箱,登录一个页面.我们经常会在此时设置30天内记住我,或者自动登录选项.那么它们是怎么记录信息的呢,答案就是今天的主 ...

  8. Linux常见后缀缩写含义

    ctl: control rc: run control (A run-control file is a file of declarations or commands associated wi ...

  9. CREATE TABLE 语句后的 ON [PRIMARY] 起什么作用

    CREATE   TABLE   [dbo].[table1]   ( [gh]   [char]   (10)   COLLATE   Chinese_PRC_CI_AS   NOT   NULL ...

  10. MeayunDB-高性能分布式内存数据库

    MeayunDB(www.meayun.com)是一款分布式的NoSQL列式内存数据库,由C#编写,主要为高性能,高并发,高可伸缩及大数据系统提供技术解决方案.基于MeayunDB,可以简单,快速的构 ...