HDU 5033 Building(单调栈)
HDU 5033 Building(单调栈)
题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5033
Description
Once upon a time Matt went to a small town. The town was so small and narrow that he can regard the town as a pivot. There were some skyscrapers in the town, each located at position xi with its height hi. All skyscrapers located in different place. The skyscrapers had no width, to make it simple. As the skyscrapers were so high, Matt could hardly see the sky.Given the position Matt was at, he wanted to know how large the angle range was where he could see the sky. Assume that Matt's height is 0. It's guaranteed that for each query, there is at least one building on both Matt's left and right, and no building locate at his position.
Input
The first line of the input contains an integer T, denoting the number of testcases. Then T test cases follow.
Each test case begins with a number N(1<=N<=10^5), the number of buildings.
In the following N lines, each line contains two numbers, xi(1<=xi<=10^7) and hi(1<=hi<=10^7).
After that, there's a number Q(1<=Q<=10^5) for the number of queries.
In the following Q lines, each line contains one number qi, which is the position Matt was at.
Output
For each test case, first output one line "Case #x:", where x is the case number (starting from 1).
Then for each query, you should output the angle range Matt could see the sky in degrees. The relative error of the answer should be no more than 10^(-4).
Sample Input
3
3
1 2
2 1
5 1
1
4
3
1 3
2 2
5 1
1
4
3
1 4
2 3
5 1
1
4
Sample Output
Case #1:
101.3099324740
Case #2:
90.0000000000
Case #3:
78.6900675260
题意:
在一条坐标轴上给你n个楼的高度,再问你再某个坐标你所能看到天空的最大视角。
题解:
首先这个数据范围明显不能105*105暴力跑。在看了题解之后,了解到可以用一个叫做单调栈的东西。当规定了栈顶到栈低的顺序,那么在每次压栈的时候则考虑是否满足这个顺序,满足入栈,不满足栈顶弹出然后直到满足压栈。
首先是最大角度,这里首先使用了一个非常巧妙的方式。
首先我们可以将这个夹角看成以该点作垂线和左右两条之间的夹角之和。这样如果我们可以将该点的垂线和左边直线之间的夹角,再将坐标轴翻转,那么右边同样变成了上一个求出的方法,累加就好。
下面就是求垂线和左边的夹角。
这里某份题解同样用了一个非常巧妙的方式,因为查询点是高度为0,那么我们先把该点的纵坐标记作查询的顺序的负数(再按照横坐标顺序从小到大排序)。这样再后面的时候可以容易的判断是否为观察点,和容易记录半边角。
下面我们遍历所有的点,首先对于该点是查询点,那么我们开始判断栈顶的点能不能遮挡次栈顶的点,如果不能那么在后面的判断中也是不能遮挡的,则该点出栈,没有价值。直到找到这个点那么通过观察点的负值取负记录角度到输出结果。
对于非观察点,我们首先是判断该点是否比栈顶元素高,高的话明显可以遮挡出栈,不比栈顶元素高的的话我们再通过判断能否遮挡来确定栈顶元素是否出栈,然后将该点入栈。
判断函数,首先我们确定三个点a,b,c。c点是观察点,a的高度>b的高度,在我们建这个单调栈的时候我们就已经保证了这个。那么判断a->c的角度和b->c的角度,即可判断是否遮挡了。
代码:
#include <bits/stdc++.h>
using namespace std;
const double PI = acos(-1.0) ;
const int maxn = 100000+100;
struct Point {
int x,h;
bool operator < (const Point &R) const {
return x < R.x ;
}
};
Point s[maxn*2];
Point stk[maxn*2];
double ans[maxn] ;
int judge(Point a,Point b,Point c)
{
if (c.h <= 0) c.h = 0;
return (long long)(a.h-c.h)*(b.x-c.x) <= (long long)(b.h-c.h)*(a.x-c.x) ;
}
double angle(Point a,Point b)
{
return atan(1.0*(b.x-a.x)/a.h) ;
}
int n,q;
void solve()
{
int top = 0;
for (int i = 0; i < n+q; i++){
if (s[i].h <= 0){
while (top >= 2 && judge(stk[top-2],stk[top-1],s[i]))
top-- ;
ans[-s[i].h] += angle(stk[top-1],s[i]) ;
}else {
while (top && stk[top-1].h <= s[i].h)
top-- ;
while (top >= 2 && judge(stk[top-2],stk[top-1],s[i]))
top--;
stk[top++] = s[i] ;
}
}
}
int main()
{
int t;
scanf("%d",&t);
for (int _t = 1;_t <= t;_t++){
scanf("%d",&n);
for (int i = 0; i < n; i++)
scanf("%d %d",&s[i].x,&s[i].h) ;
scanf("%d",&q) ;
for (int i = 0; i < q; i++){
scanf("%d",&s[i+n].x);
s[i+n].h = -i;
}
memset(ans,0,sizeof ans) ;
sort(s,s+n+q) ;
solve();
reverse(s,s+n+q) ;
for (int i = 0; i < n+q; i++)
s[i].x = 10000000-s[i].x ;
solve() ;
printf("Case #%d:\n",_t) ;
for (int i = 0 ; i <q; i++)
printf("%.10lf\n",ans[i]*180/PI) ;
}
return 0;
}
HDU 5033 Building(单调栈)的更多相关文章
- 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 (单调栈+倍增)
题意:有一排建筑,每座建筑有一定的高度,宽度可以忽略,求在某点的平地上能看到天空的最大角度. 网上的做法基本都是离线的...其实这道题是可以在线做的. 对于向右能看到的最大角度,从右往左倍增维护每个时 ...
- HDU 5033 Building(单调栈维护凸包)
盗张图:来自http://blog.csdn.net/xuechelingxiao/article/details/39494433 题目大意:有一排建筑物坐落在一条直线上,每个建筑物都有一定的高度, ...
- hdu - 5033 - Building(单调栈)
题意:N 幢楼排成一列(1<=N<=10^5),各楼有横坐标 xi(1<=xi<=10^7) 以及高度 hi(1<=hi<=10^7),在各楼之间的Q个位置(1&l ...
- 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 (维护单调栈)
题目链接 题意:n个建筑物,Q条询问,问所在的位置,看到天空的角度是多少,每条询问的位置左右必定是有建筑物的. 思路 : 维护一个单调栈,将所有的建筑物和所有的人都放到一起开始算就行,每加入一个人,就 ...
- hdu 5033 模拟+单调优化
http://acm.hdu.edu.cn/showproblem.php?pid=5033 平面上有n个建筑,每个建筑由(xi,hi)表示,m组询问在某一个点能看到天空的视角范围大小. 维护一个凸包 ...
- Largest Rectangle in a Histogram HDU - 1506 (单调栈)
A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rec ...
- HDU5033 building 单调栈+计算几何
正解:单调栈 解题报告: 哇生气辽QAQ本来打了半天feel good都快调出来了然后说换题了QAQ(所以可能那题的代码会过一阵子再放上来了QAQ 不过还是大爆手速打了一通拿到首杀了嘻嘻 美滋滋辽 然 ...
随机推荐
- enode框架step by step之事件驱动架构(EDA)思想的在框架中如何体现
enode框架step by step之事件驱动架构(EDA)思想的在框架中如何体现 上一篇文章,我给大家分享了我的一个基于DDD以及EDA架构的框架enode,但是只是介绍了一个大概.接下来我准备用 ...
- C#多线程解决界面卡死问题
C#多线程解决界面卡死问题的完美解决方案 文章下最方有源码下载 问题描述:当我们的界面需要在程序运行中不断更新数据时, 当一个textbox的数据需要变化时, 对于这个问题可以先参考下我的另外一个文章 ...
- ERROR 1130: Host xxx is not allowed to connect to this MySQL server
在使用MySQL-Front连接mysql的时候发生的这个错误 ERROR 1130: Host xxx is not allowed to connect to this MySQL server ...
- Scrapy 通过登录的方式爬取豆瓣影评数据
Scrapy 通过登录的方式爬取豆瓣影评数据 爬虫 Scrapy 豆瓣 Fly 由于需要爬取影评数据在来做分析,就选择了豆瓣影评来抓取数据,工具使用的是Scrapy工具来实现.scrapy工具使用起来 ...
- iOS 指南针的制作 附带源码
iOS 指南针的制作 附带源码 代码下载地址: http://vdisk.weibo.com/s/HK4yE http://pan.baidu.com/share/link?shareid=7 ...
- Android 权限管理
从 Android 6.0(API 级别 23)开始,用户开始在应用运行时向其授予权限,而不是在应用安装时授予.此方法可以简化应用安装过程,因为用户在安装或更新应用时不需要授予权限.它还让用户可以对应 ...
- 【转】HTTP Response Header 的 Content-Disposition
因为听到有同事讨论JSP输出Excel文件的,就是在页面上有一个[导出]按钮,能够将查询结果导出到Excel文件让用户下载.有人说要用POI在后台生成临时的Excel文件,然后通过读取FileStre ...
- JAVA 代码开发规范
一.开发工具规范: 1. 开发工具经项目负责人调试后统一确定. 2. 开发工具一经确定不允许集成任何非统一插件,若有需要,经项目负责人同意后统一为 项目组成员添加. 3. 开发工具的编码格式不允许修改 ...
- 驱动09.nand flash
1 nand flash的操作 目的:读地址A的数据,把数据B写到地址A. 问1. 原理图上NAND FLASH和S3C2440之间只有数据线,怎么传输地址?答1.在DATA0-DATA7上既传输数据 ...
- CentOS Gnome 识别 NTFS-3G
安装完NTFS-3G后,使用命令行已经可以正常挂载NTFS分区了 但如果是源码编译安装(epel yum 库也有),还需要添加一个软链接,才能点击Gnome的左边栏进行挂载,因为Gnome挂载NTFS ...
题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5033
Description
Once upon a time Matt went to a small town. The town was so small and narrow that he can regard the town as a pivot. There were some skyscrapers in the town, each located at position xi with its height hi. All skyscrapers located in different place. The skyscrapers had no width, to make it simple. As the skyscrapers were so high, Matt could hardly see the sky.Given the position Matt was at, he wanted to know how large the angle range was where he could see the sky. Assume that Matt's height is 0. It's guaranteed that for each query, there is at least one building on both Matt's left and right, and no building locate at his position.
Input
The first line of the input contains an integer T, denoting the number of testcases. Then T test cases follow.
Each test case begins with a number N(1<=N<=10^5), the number of buildings.
In the following N lines, each line contains two numbers, xi(1<=xi<=10^7) and hi(1<=hi<=10^7).
After that, there's a number Q(1<=Q<=10^5) for the number of queries.
In the following Q lines, each line contains one number qi, which is the position Matt was at.
Output
For each test case, first output one line "Case #x:", where x is the case number (starting from 1).
Then for each query, you should output the angle range Matt could see the sky in degrees. The relative error of the answer should be no more than 10^(-4).
Sample Input
3
3
1 2
2 1
5 1
1
4
3
1 3
2 2
5 1
1
4
3
1 4
2 3
5 1
1
4
Sample Output
Case #1:
101.3099324740
Case #2:
90.0000000000
Case #3:
78.6900675260
题意:
在一条坐标轴上给你n个楼的高度,再问你再某个坐标你所能看到天空的最大视角。
题解:
首先这个数据范围明显不能105*105暴力跑。在看了题解之后,了解到可以用一个叫做单调栈的东西。当规定了栈顶到栈低的顺序,那么在每次压栈的时候则考虑是否满足这个顺序,满足入栈,不满足栈顶弹出然后直到满足压栈。
首先是最大角度,这里首先使用了一个非常巧妙的方式。首先我们可以将这个夹角看成以该点作垂线和左右两条之间的夹角之和。这样如果我们可以将该点的垂线和左边直线之间的夹角,再将坐标轴翻转,那么右边同样变成了上一个求出的方法,累加就好。
下面就是求垂线和左边的夹角。
这里某份题解同样用了一个非常巧妙的方式,因为查询点是高度为0,那么我们先把该点的纵坐标记作查询的顺序的负数(再按照横坐标顺序从小到大排序)。这样再后面的时候可以容易的判断是否为观察点,和容易记录半边角。
下面我们遍历所有的点,首先对于该点是查询点,那么我们开始判断栈顶的点能不能遮挡次栈顶的点,如果不能那么在后面的判断中也是不能遮挡的,则该点出栈,没有价值。直到找到这个点那么通过观察点的负值取负记录角度到输出结果。
对于非观察点,我们首先是判断该点是否比栈顶元素高,高的话明显可以遮挡出栈,不比栈顶元素高的的话我们再通过判断能否遮挡来确定栈顶元素是否出栈,然后将该点入栈。判断函数,首先我们确定三个点a,b,c。c点是观察点,a的高度>b的高度,在我们建这个单调栈的时候我们就已经保证了这个。那么判断a->c的角度和b->c的角度,即可判断是否遮挡了。
代码:
#include <bits/stdc++.h>
using namespace std;
const double PI = acos(-1.0) ;
const int maxn = 100000+100;
struct Point {
int x,h;
bool operator < (const Point &R) const {
return x < R.x ;
}
};
Point s[maxn*2];
Point stk[maxn*2];
double ans[maxn] ;
int judge(Point a,Point b,Point c)
{
if (c.h <= 0) c.h = 0;
return (long long)(a.h-c.h)*(b.x-c.x) <= (long long)(b.h-c.h)*(a.x-c.x) ;
}
double angle(Point a,Point b)
{
return atan(1.0*(b.x-a.x)/a.h) ;
}
int n,q;
void solve()
{
int top = 0;
for (int i = 0; i < n+q; i++){
if (s[i].h <= 0){
while (top >= 2 && judge(stk[top-2],stk[top-1],s[i]))
top-- ;
ans[-s[i].h] += angle(stk[top-1],s[i]) ;
}else {
while (top && stk[top-1].h <= s[i].h)
top-- ;
while (top >= 2 && judge(stk[top-2],stk[top-1],s[i]))
top--;
stk[top++] = s[i] ;
}
}
}
int main()
{
int t;
scanf("%d",&t);
for (int _t = 1;_t <= t;_t++){
scanf("%d",&n);
for (int i = 0; i < n; i++)
scanf("%d %d",&s[i].x,&s[i].h) ;
scanf("%d",&q) ;
for (int i = 0; i < q; i++){
scanf("%d",&s[i+n].x);
s[i+n].h = -i;
}
memset(ans,0,sizeof ans) ;
sort(s,s+n+q) ;
solve();
reverse(s,s+n+q) ;
for (int i = 0; i < n+q; i++)
s[i].x = 10000000-s[i].x ;
solve() ;
printf("Case #%d:\n",_t) ;
for (int i = 0 ; i <q; i++)
printf("%.10lf\n",ans[i]*180/PI) ;
}
return 0;
}
Description Once upon a time Matt went to a small town. The town was so small and narrow that he can ...
题意:有一排建筑,每座建筑有一定的高度,宽度可以忽略,求在某点的平地上能看到天空的最大角度. 网上的做法基本都是离线的...其实这道题是可以在线做的. 对于向右能看到的最大角度,从右往左倍增维护每个时 ...
盗张图:来自http://blog.csdn.net/xuechelingxiao/article/details/39494433 题目大意:有一排建筑物坐落在一条直线上,每个建筑物都有一定的高度, ...
题意:N 幢楼排成一列(1<=N<=10^5),各楼有横坐标 xi(1<=xi<=10^7) 以及高度 hi(1<=hi<=10^7),在各楼之间的Q个位置(1&l ...
做了三天,,,终于a了... 11724203 2014-09-25 09:37:44 Accepted 5033 781MS 7400K 4751 B G++ czy Building Time L ...
题目链接 题意:n个建筑物,Q条询问,问所在的位置,看到天空的角度是多少,每条询问的位置左右必定是有建筑物的. 思路 : 维护一个单调栈,将所有的建筑物和所有的人都放到一起开始算就行,每加入一个人,就 ...
http://acm.hdu.edu.cn/showproblem.php?pid=5033 平面上有n个建筑,每个建筑由(xi,hi)表示,m组询问在某一个点能看到天空的视角范围大小. 维护一个凸包 ...
A histogram is a polygon composed of a sequence of rectangles aligned at a common base line. The rec ...
正解:单调栈 解题报告: 哇生气辽QAQ本来打了半天feel good都快调出来了然后说换题了QAQ(所以可能那题的代码会过一阵子再放上来了QAQ 不过还是大爆手速打了一通拿到首杀了嘻嘻 美滋滋辽 然 ...
enode框架step by step之事件驱动架构(EDA)思想的在框架中如何体现 上一篇文章,我给大家分享了我的一个基于DDD以及EDA架构的框架enode,但是只是介绍了一个大概.接下来我准备用 ...
C#多线程解决界面卡死问题的完美解决方案 文章下最方有源码下载 问题描述:当我们的界面需要在程序运行中不断更新数据时, 当一个textbox的数据需要变化时, 对于这个问题可以先参考下我的另外一个文章 ...
在使用MySQL-Front连接mysql的时候发生的这个错误 ERROR 1130: Host xxx is not allowed to connect to this MySQL server ...
Scrapy 通过登录的方式爬取豆瓣影评数据 爬虫 Scrapy 豆瓣 Fly 由于需要爬取影评数据在来做分析,就选择了豆瓣影评来抓取数据,工具使用的是Scrapy工具来实现.scrapy工具使用起来 ...
iOS 指南针的制作 附带源码 代码下载地址: http://vdisk.weibo.com/s/HK4yE http://pan.baidu.com/share/link?shareid=7 ...
从 Android 6.0(API 级别 23)开始,用户开始在应用运行时向其授予权限,而不是在应用安装时授予.此方法可以简化应用安装过程,因为用户在安装或更新应用时不需要授予权限.它还让用户可以对应 ...
因为听到有同事讨论JSP输出Excel文件的,就是在页面上有一个[导出]按钮,能够将查询结果导出到Excel文件让用户下载.有人说要用POI在后台生成临时的Excel文件,然后通过读取FileStre ...
一.开发工具规范: 1. 开发工具经项目负责人调试后统一确定. 2. 开发工具一经确定不允许集成任何非统一插件,若有需要,经项目负责人同意后统一为 项目组成员添加. 3. 开发工具的编码格式不允许修改 ...
1 nand flash的操作 目的:读地址A的数据,把数据B写到地址A. 问1. 原理图上NAND FLASH和S3C2440之间只有数据线,怎么传输地址?答1.在DATA0-DATA7上既传输数据 ...
安装完NTFS-3G后,使用命令行已经可以正常挂载NTFS分区了 但如果是源码编译安装(epel yum 库也有),还需要添加一个软链接,才能点击Gnome的左边栏进行挂载,因为Gnome挂载NTFS ...