HDU 5033 Building --离线+单调栈
题意:给一些建筑物,x表示横坐标,h表示高度,然后查询某些坐标x,问从该点看向天空的最大张角是多大。
解法:离线操作,读入所有数据,然后按x升序排序,对每一个查询的x,先从左到右,依次添加x坐标小于x的建筑物,加入一个建筑物的条件:
1.此建筑物高度大于栈中的前一个,这个必然是最优的。
2.加入这个建筑物后不能使相对斜率: stk[top-2]~stk[top-1] 比a[j]~stk[top-1]大(负数),即出现凹形,否则会出现这种:

如图,即中间那个根本没用了,加入第三根的时候就要判一下。
最后算这个查询x的左角度的时候,要先判断这个点跟栈中上面两个的关系,处理一下。
然后再从右到左扫一遍,最后就得出了左右角。
之前没考虑相对斜率,而是每次加建筑物的时候,只判断与此时的查询点的绝对斜率关系,这样的bug就是会形成上图中的情况。(好蒻)
代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#define pi (acos(-1.0))
#define eps 1e-7
using namespace std;
#define N 100007 struct Query
{
double x;
double Lang,Rang;
int ind;
}ans[N]; struct node
{
double x,h;
}a[N];
int stk[N],top;
int cmp1(Query ka,Query kb) { return ka.x < kb.x; }
int cmp2(Query ka,Query kb) { return ka.ind < kb.ind; }
int cmpB(node ka,node kb) { return ka.x < kb.x; } int main()
{
int t,cs = ,i,j;
int n,m;
scanf("%d",&t);
while(t--)
{
scanf("%d",&n);
for(i=;i<=n;i++)
scanf("%lf%lf",&a[i].x,&a[i].h);
sort(a+,a+n+,cmpB);
scanf("%d",&m);
for(i=;i<=m;i++)
{
scanf("%lf",&ans[i].x);
ans[i].ind = i;
}
sort(ans+,ans+m+,cmp1);
double now;
top = ;
j = ;
for(i=;i<=m;i++)
{
while(j <= n && a[j].x < ans[i].x)
{
while(top >= && a[j].h >= a[stk[top-]].h) //高度大于之前的,肯定更优
top--;
while(top >= && (a[j].h-a[stk[top-]].h)/(fabs(a[j].x-a[stk[top-]].x)) >= (a[stk[top-]].h-a[stk[top-]].h)/(fabs(a[stk[top-]].x-a[stk[top-]].x)))
top--; //相对斜率递减(负数)
stk[top++] = j;
j++;
}
while(top >= && a[stk[top-]].h/(fabs(a[stk[top-]].x-ans[i].x)) <= a[stk[top-]].h/(fabs(a[stk[top-]].x-ans[i].x)))
top--; //对这个点
now = a[stk[top-]].h/(fabs(a[stk[top-]].x-ans[i].x)); //最终答案为栈顶的建筑
ans[i].Lang = 180.0*atan2(now,1.0)/pi;
}
top = ; //反着来一遍
j = n;
for(i=m;i>=;i--)
{
while(j >= && a[j].x > ans[i].x)
{
while(top >= && a[j].h >= a[stk[top-]].h)
top--;
while(top >= && (a[j].h-a[stk[top-]].h)/(fabs(a[j].x-a[stk[top-]].x)) >= (a[stk[top-]].h-a[stk[top-]].h)/(fabs(a[stk[top-]].x-a[stk[top-]].x)))
top--;
stk[top++] = j;
j--;
}
while(top >= && a[stk[top-]].h/(fabs(a[stk[top-]].x-ans[i].x)) <= a[stk[top-]].h/(fabs(a[stk[top-]].x-ans[i].x)))
top--;
now = a[stk[top-]].h/(fabs(a[stk[top-]].x-ans[i].x));
ans[i].Rang = 180.0*atan2(now,1.0)/pi;
}
sort(ans+,ans+m+,cmp2);
printf("Case #%d:\n",cs++);
for(i=;i<=m;i++)
printf("%.10f\n",180.0-ans[i].Lang-ans[i].Rang);
}
return ;
}
HDU 5033 Building --离线+单调栈的更多相关文章
- hdu - 5033 - Building(单调栈)
题意:N 幢楼排成一列(1<=N<=10^5),各楼有横坐标 xi(1<=xi<=10^7) 以及高度 hi(1<=hi<=10^7),在各楼之间的Q个位置(1&l ...
- HDU 5033 Building (维护单调栈)
题目链接 题意:n个建筑物,Q条询问,问所在的位置,看到天空的角度是多少,每条询问的位置左右必定是有建筑物的. 思路 : 维护一个单调栈,将所有的建筑物和所有的人都放到一起开始算就行,每加入一个人,就 ...
- hdu 5033 buiding(单调栈)
hdu 5033 buiding(单调栈) 某年某月某天,马特去了一个小镇.这个小镇如此狭窄,以至于他可以把小镇当作一个枢纽.在镇上有一些摩天大楼,其中一栋位于xi,高度为hi.所有的摩天大楼位于不同 ...
- HDU 5033 Building(单调栈)
HDU 5033 Building(单调栈) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5033 Description Once upon a ti ...
- HDU 5033 Building(北京网络赛B题) 单调栈 找规律
做了三天,,,终于a了... 11724203 2014-09-25 09:37:44 Accepted 5033 781MS 7400K 4751 B G++ czy Building Time L ...
- hdu 5033 Building (单调栈 或 暴力枚举 )
Description Once upon a time Matt went to a small town. The town was so small and narrow that he can ...
- HDU - 5033 Building (单调栈+倍增)
题意:有一排建筑,每座建筑有一定的高度,宽度可以忽略,求在某点的平地上能看到天空的最大角度. 网上的做法基本都是离线的...其实这道题是可以在线做的. 对于向右能看到的最大角度,从右往左倍增维护每个时 ...
- hdu5033 Building (单调栈+)
http://acm.hdu.edu.cn/showproblem.php?pid=5033 2014 ACM/ICPC Asia Regional Beijing Online B 1002 Bui ...
- HDU 2870 Largest Submatrix (单调栈)
http://acm.hdu.edu.cn/showproblem.php? pid=2870 Largest Submatrix Time Limit: 2000/1000 MS (Java/Oth ...
随机推荐
- mybatis 下划线转驼峰配置
一直以来,在sqlmap文件中,对于数据库中的下划线字段转驼峰,我们都是通过resultmap来做的,如下: <resultMap id="ISTableStatistics" ...
- 每日微软面试题——day 6(打印所有对称子串)
每日微软面试题——day 6(打印所有对称子串) 分类: 2.数据结构与算法2011-08-14 14:27 9595人阅读 评论(15) 收藏 举报 面试微软string测试systemdistan ...
- [js开源组件开发]图片懒加载lazyload
图片懒加载lazyload 前端对请求的一种优化方式,为什么叫懒加载,无从查起,反正我当初一直认为它是滚动加载的一种类型.它主要是以图片或背景在可视区域内时才显示真正的图片,减少src带来的负荷.所以 ...
- MUI - 将tap模拟成原生click体验
mui提供了tap事件替换了html5的click事件,解决了300ms延时的问题.不过相比原生app的click体验还是有些许差距的.关于300ms延时的问题,这篇帖子分析的比较完善,其中提到了穿透 ...
- Atitit.木马 病毒 免杀 技术 360免杀 杀毒软件免杀 原理与原则 attilax 总结
Atitit.木马 病毒 免杀 技术 360免杀 杀毒软件免杀 原理与原则 attilax 总结 1. ,免杀技术的用途2 1.1. 病毒木马的编写2 1.2. 软件保护所用的加密产品(比如壳)中,有 ...
- Nunit在VS2010加载不了程序集的解决办法
本机环境: Win7 64位 旗舰版 VS2010 Nunit2.6.3 故障重现步骤: 1.在启动外部应用程序中增加C:\Program Files (x86)\NUnit 2.6.3\bin\nu ...
- RecyclerView添加头部和底部视图的实现
ListView是有addHeaderView和 addFooterView两个方法的. 但是作为官方推荐的ListView的升级版RecyclerView缺无法实现这两个方法. 那么如果使用Recy ...
- BI笔记-SSAS部署的几种方式及部署后的SSAS刷新
SSAS的部署方式在哥本哈士奇的博客:BI笔记之--- SSAS部署的几种方式已经介绍了四种方式,在这里再介绍一种比较常用的快速部署方式. 环境约定:SQL Server 2008 R2 示例库:Ad ...
- JAVA基础学习day13--String、StringBuilder与StringBuffer与包装类
一.String 1.1.String String 类是final修饰的,是顶级类,不可被继承 String 类代表字符串.Java 程序中的所有字符串字面值(如 "abc" ) ...
- 【转】IOS设备旋转的内部处理流程以及一些【优化建议】
加速计是整个IOS屏幕旋转的基础,依赖加速计,设备才可以判断出当前的设备方向,IOS系统共定义了以下七种设备方向: typedef NS_ENUM(NSInteger, UIDeviceOrienta ...