//    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. 个人简历(中英对照)词汇大全
  3. 程序员都应了解的 CDN 是什么?
  4. vue 导入excel解析_Vue实现Excel导入并解析
  5. 继电保护整定值计算软件_继电保护整定计算软件
  6. Strom和Trident
  7. Linux Puppet基础知识
  8. TLS原理及证书生成
  9. Nova API服务之Nova API服务的启动
  10. 聚力优创:拼多多的店铺怎么引流?秘诀分享
  11. 应用层与HTTP协议
  12. 永恒之蓝漏洞获取桌面截图
  13. 发射功率 dBm 计算
  14. Possibly consider using a shorter maxLifetime value.解决方法
  15. 用计算机观察声音的波形,用几何画板观察声音的波形
  16. MVG(second)学习笔记- 摄像机模型
  17. 食物同时食用是否有害健康
  18. 达索SIMULIA多物理场仿真解决方案
  19. 京东联盟开发(11)——商品类目(2级)
  20. 【ChatGPT】ChatGPT 在智能客服产品如何落地?

热门文章

  1. 如何使用Xilisoft Video Editor快速剪切视频
  2. Atlassian发布Bamboo 6.0和Bitbucket Server 5.0
  3. Debian更新软件源提示There is no public key available for the following key IDs的解决方法
  4. Android Messenger 跨进程通信
  5. 在服务器上log4net没写日志
  6. 工厂模型——简单工厂和工厂方法
  7. [跪了]Servlet 工作原理解析
  8. 阿里的dubbo 到底是用来干嘛的?
  9. 《深入理解Java虚拟机》读书总结
  10. 瞧瞧,人家这后端API接口写得,那叫一个巴适~,再看看我的,像坨屎!