题意:给一些建筑物,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. 多准则决策模型-TOPSIS评价方法-源码

    ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 ...

  2. 关联规则-R语言实现

    关联规则code{white-space: pre;} pre:not([class]) { background-color: white; }if (window.hljs && ...

  3. javascript中静态方法、实例方法、内部方法和原型的一点见解

    1.静态方法的定义 var BaseClass = function() {}; // var BaseClass=new Function(); BaseClass.f1 = function(){ ...

  4. ABAP内表(internal table)有关的系统变量

    SY-TABIX – 内表当前行的索引号.SY-TABIX 的值可以被以下命令修改,但是只适用于索引表(index table).对于哈希表(Hashed table),这个系统变量的值为空或0. A ...

  5. vIDC v2.0 强大的端口转发神器使用总结-开放内网tfs代码服务

    vIDC2.0 端口映射工具,最近在公司闲来无事,想自己整个tfs来管理自己的研究代码. 本来是想用微软Visual Studio提供的免费tfs,但是无奈速度太慢.他们的服务器在美国,中国也没有代理 ...

  6. Sharepoint学习笔记—习题系列--70-573习题解析 -(Q104-Q106)

    Question 104You plan to create a workflow that has the following three activities: CreateTask OnTask ...

  7. Mac下利用(xcode)安装git

    Mac下利用(xcode)安装git 一.AppStore 最安全途径:搜索下载Xcode,(需要AppleID). 其他:直接百度Xcode下载. 二.Xcode 打开Xcode-->Pref ...

  8. C语言原子接口与实现

    原子是一个指向唯一的.不可变的0个或任意多个字节序列的指针,大多数原子都是指向以空字符结束的字符串,但是任何一个指向任意字节序列的指针都可以使原子.任何原子只能出现一次.如果两个原子指向同一个内存单元 ...

  9. CocoaPod出现-bash: pod: command not found 解决办法

    从过年来到公司  就不用自己电脑了    之前一直自己带电脑   昨天随便建了一个demo   使用cocoapods  发现     -bash: pod: command not found 刚开 ...

  10. android学习笔记 activity生命周期&任务栈&activity启动模式

    activity生命周期 完整生命周期 oncreate->onstart->onresume->onpause->onstop->ondestory 使用场景:应用程序 ...