//    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(); } }

转载于:https://www.cnblogs.com/llguanli/p/7002057.html

hdu5033 Building 单调队列相关推荐

  1. 【数据结构】单调栈和单调队列 详解+例题剖析

    算法:单调栈和单调队列 一.单调栈和单调队列 二.单调栈例题 1.模板题入门 2.不懂不要急,看这道题 三.单调队列例题 1.入门 2.进阶 一.单调栈和单调队列 单调栈和单调队列与普通的栈,队列不同 ...

  2. 单调队列多重背包时间复杂度O(vn)

    版权声明:本文为博主原创文章,未经博主允许不得转载. 多重背包问题: 有N种物品和容量为V的背包,若第i种物品,容量为v[i],价值为w[i],共有n[i]件.怎样装才能使背包内的物品总价值最大? 网 ...

  3. 洛谷 P2219修筑绿化带 二维单调队列~

    题目链接:https://www.luogu.org/problem/P2219 emmm调了一个上午+中午,fan 题意:从N*M的中找到一个a*b的大矩形和减去a*b中的一个与之不重边界的c*d的 ...

  4. P2216 理想的正方形 单调队列 (二维)

    题目链接:https://www.luogu.org/problem/P2216 题意:求给定n*m的矩形中所有k*k的正方形块中最大值最小值之差(极差)最小 哇,大神的思路真的很帅 单调队列对每一行 ...

  5. 点分治问题 ----------- luoguP2942 [WC2010]重建计划 [点分治 + bfs + 单调队列 + 预处理建树 + 二分 + 01分数规划]

    题目链接 解题思路: 1.对于这个Avgvalue=∑e∈sv(e)∣s∣Avgvalue = \frac{\sum_{e\in s}v(e)}{|s|}Avgvalue=∣s∣∑e∈s​v(e)​ ...

  6. 解题报告:Fake Maxpooling(单调队列求矩阵的和)

    我们不妨先把这个问题中二维的矩阵简化成一维的数列.那么现在的问题就变成了一个求连续的滑动窗口最值问题:给出一个长度为n的数列和一个长度为k(k<n)的窗口,记录滑动窗口位于每个位置下的下的最大值 ...

  7. 0x12.基本数据结构 — 队列与单调队列

    目录 一.队列 0.UVA540 团体队列 Team Queue 1.AcWing 133. 蚯蚓(模拟优先队列) 二 .单调队列 0.AcWing 135. 最大子序和(单调队列) 1.luogu ...

  8. 【题解】P1419 寻找段落(二分+单调队列)难度⭐⭐⭐★

    P1419 寻找段落 首先二分答案,即:二分最大平均值. 我们将a全部减去mid,问题转化为判断是否存在一个长度在s~t范围内的区间它的和为正,如果有说明还有更大的平均值. 用前缀和和单调队列维护. ...

  9. HDU 5289 Assignment(单调队列)

    题意:给T足数据,然后每组一个n和k,表示n个数,k表示最大同意的能力差,接下来n个数表示n个人的能力,求能力差在k之内的区间有几个 分析:维护一个区间的最大值和最小值,使得他们的差小于k,于是採用单 ...

  10. 算法笔记--单调队列优化dp

    单调队列:队列中元素单调递增或递减,可以用双端队列实现(deque),队列的前面和后面都可以入队出队. 单调队列优化dp: 问题引入: dp[i] = min( a[j] ) ,i-m < j ...

最新文章

  1. 学会这门编程知识,可能决定你能进什么样的企业
  2. OC 知识:彻底理解 iOS 内存管理(MRC、ARC)
  3. json_encode用法
  4. Sublime Text 3 初试牛刀
  5. 站长seo经过的阶段
  6. VS2010中的单元测试【转载】
  7. 编解码格式 -- AAC
  8. sql 按名称首字母拼音排序
  9. 介绍一款rar文件密码破解利器——RAR Password Unlocker
  10. 区块链大咖谈之董天一:深度理解IPFS与Filecoin应用的几个关键点
  11. “一对一直播源码开发”运筹帷幄之中,决胜千里之外
  12. 在阿里云服务器上运行自己的Python程序(Linux系统)
  13. Android---MVC/MVP/MVVM的演进
  14. Android 一个简单的音乐播放器
  15. html怎么在手机打不开,手机百度打不开网页怎么办 解决方法
  16. UE4 凹多边形渲染
  17. Go语言6种字符串拼接的方式
  18. VBA基础语法:循环语句
  19. 360数科华丽财报下的增长困局
  20. Gate 7.2的学习笔记(一)

热门文章

  1. 只需简单的整理,让你的Mac 更安全、更智能
  2. 如何在Mac上使用触控栏?
  3. 在 Mac 上的“访达”中排序和排列项目
  4. django为Form生成的label标签添加class
  5. Linux 命令整理-tailf
  6. java泛型好处及案例
  7. Linux突然断电后文件丢失的问题
  8. UNIX环境高级编程——记录上锁(fcntl函数)以及死锁检测
  9. python入门(1)文档的处理
  10. MySQL essential版本和普通版本有什么区别?