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 ...
随机推荐
- java ftp
FTPUtil import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import jav ...
- EffectiveJava——接口优于抽象类
Java程序设计语言提供两种机制,可以用来定义允许多个实现的类型:接口和抽象方法,这两者直接醉为明显的区别在于,抽象类允许某些方法的实现,但接口不允许,一个更为重要的区别在于,为了实现由抽象类定义的类 ...
- 微软Asp.net MVC5生命周期流程图
.NET WEB Development blog 发布了Asp.net MVC5生命周期文档, 这个文档类似Asp.net应用程序生命周期,您以前开发ASP.NET WEB应用程序应该 ...
- 初识 easyui datagrid
首先应该下载好easyui datagrid所用的各种js 和css 这个可以到官网上去下载. 首先要引入datagrid所引入的js和css. <script src="js/jqu ...
- jvisualvm远程监控jvm设置
有些时候,需要对特定环境中的Java应用进行实时性能分析,大部分非开发和测试环境,一般都是用jvisualvm进行基本检测以最小化对系统的影响(其开启后,负载影响大约20%-30%),jvisualv ...
- java调用html模板发送html内容的邮件
在项目需要发送邮件,普通内容的邮件觉得太单调.太丑,没逼格,所以说直接把用到的邮件内容做成一个html模板,发送之前将对应参数替换掉,发送html内容的高逼格邮件. 首先需要引用jar包,这就不多说了 ...
- android:#FFFFFFFF 颜色码解析
原文地址:android:#FFFFFFFF 颜色作者:android小鸟 颜色色码为#FFFFFFFF 其中颜色顺序依次为#AARRGGBB 前两位AA代表透明度,FF时表示不透明,00表示透明: ...
- Python学习一入门
一.打印Hello和多行文本 print 打印 后跟单引号或者双引号 多行:3个单引号或者3个双引号 二.算术运算 2.1.加减乖法 默认1/2=0 如果需要小数运算,则需要一个运算术上加.或者.0 ...
- 通过注册的URL Scheme向目标APP传递参数
通过注册的URL Scheme向目标APP传递参数 通过URL Scheme启动APP很简单就可以做到,但有时候我们想在启动APP的时候传递一些参数,这个时候我们就可以通过URL Scheme自定义U ...
- abs()函数的返回值问题
转载原文地址:http://www.cnblogs.com/webary/p/4967868.html 在牛客网看到一道关于abs()函数返回值的题目,见下图,当时还没反应过来,第一反应是:自从我开始 ...