题意:给一些建筑物,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 --离线+单调栈的更多相关文章

  1. hdu - 5033 - Building(单调栈)

    题意:N 幢楼排成一列(1<=N<=10^5),各楼有横坐标 xi(1<=xi<=10^7) 以及高度 hi(1<=hi<=10^7),在各楼之间的Q个位置(1&l ...

  2. HDU 5033 Building (维护单调栈)

    题目链接 题意:n个建筑物,Q条询问,问所在的位置,看到天空的角度是多少,每条询问的位置左右必定是有建筑物的. 思路 : 维护一个单调栈,将所有的建筑物和所有的人都放到一起开始算就行,每加入一个人,就 ...

  3. hdu 5033 buiding(单调栈)

    hdu 5033 buiding(单调栈) 某年某月某天,马特去了一个小镇.这个小镇如此狭窄,以至于他可以把小镇当作一个枢纽.在镇上有一些摩天大楼,其中一栋位于xi,高度为hi.所有的摩天大楼位于不同 ...

  4. HDU 5033 Building(单调栈)

    HDU 5033 Building(单调栈) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5033 Description Once upon a ti ...

  5. HDU 5033 Building(北京网络赛B题) 单调栈 找规律

    做了三天,,,终于a了... 11724203 2014-09-25 09:37:44 Accepted 5033 781MS 7400K 4751 B G++ czy Building Time L ...

  6. hdu 5033 Building (单调栈 或 暴力枚举 )

    Description Once upon a time Matt went to a small town. The town was so small and narrow that he can ...

  7. HDU - 5033 Building (单调栈+倍增)

    题意:有一排建筑,每座建筑有一定的高度,宽度可以忽略,求在某点的平地上能看到天空的最大角度. 网上的做法基本都是离线的...其实这道题是可以在线做的. 对于向右能看到的最大角度,从右往左倍增维护每个时 ...

  8. hdu5033 Building (单调栈+)

    http://acm.hdu.edu.cn/showproblem.php?pid=5033 2014 ACM/ICPC Asia Regional Beijing Online B 1002 Bui ...

  9. HDU 2870 Largest Submatrix (单调栈)

    http://acm.hdu.edu.cn/showproblem.php? pid=2870 Largest Submatrix Time Limit: 2000/1000 MS (Java/Oth ...

随机推荐

  1. ServiceStack.Text反序列化lowercase_underscore_names格式的JSON

    代码: [Test] public void Test() { JsConfig.PropertyConvention = JsonPropertyConvention.Lenient; var js ...

  2. winform(ListView及数据库连接)

    一.ListView:列表展示数据1.视图 - 在其右上方小箭头点击将视图改为Largelcon:或右键属性在外观View将其改为Details2.设置列头 - 在其右上方小箭头点击选择编辑列,然后添 ...

  3. VS2010在空解决方案中添加项目

    如题,在空解决方案中添加第一个项目的时候会看不到那个solution解决方案文件,而是你当前添加的项目,当你再添加其他项目的时候就悲催了,找不到这个solution,只能在这个项目文件上新加文件,很郁 ...

  4. jQuery owlcarousel 旋转木马

    owlcarousel是一款猫头鹰旋转木马插件.OwlCarousel优势兼容所有浏览器支持响应式支持 CSS3 过度支持触摸事件支持 JSON 及自定义 JSON 格式支持进度条支持自定义事件支持延 ...

  5. mvc项目架构分享系列之架构搭建初步

    mvc项目架构分享系列之架构搭建初步 Contents 系列一[架构概览] 0.项目简介 1.项目解决方案分层方案 2.所用到的技术 3.项目引用关系 系列二[架构搭建初步] 4.项目架构各部分解析 ...

  6. 读书笔记2014第3本:Visual Studio程序员箴言

    Visual Studio 2010是我经常使用的程序开发工具,也知道VS中有大量的快捷键可以帮助提高效率,可惜就是不愿意记忆,最近在学vim的时候快速把<Visual Studio程序员箴言& ...

  7. 二维码扫描利用ZBar实现

    上次是根据系统的属性自己封装的一个二维码扫描,这次给大家介绍一下基于ZBar集成的类似于QQ二维码扫描界面的二维码扫描的效果.                                     ...

  8. UVa 101 - The Blocks Problem(积木问题,指令操作)

    题目来源:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&category=3&pa ...

  9. 为 Virtual Box 中的 CentOS 6.6 配置本地DVD光盘做yum软件源

    因为virtual box 中的centos配置host-only共享win7上网,配置失败,所以只能使用Centos的 DVD 光盘来配置yum软件源.不然就没得完了. 1. 首先要在virtual ...

  10. jQuery最佳实践(不断更新中...)

    1. 处理cdn失效 <script type="text/javascript" src="http://xxx.com/jquery.min.js " ...