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 不过还是大爆手速打了一通拿到首杀了嘻嘻 美滋滋辽 然 ...
随机推荐
- JVM内存管理学习总结(一)
I.JVM进程的生命周期 JVM实例的生命周期和java程序的生命周期保持一致,即一个新的程序启动则产生一个新的JVM进程实例,程序结束则JVM进程实例伴随着消失.那么程序启动和程序终止就是JVM实例 ...
- 从零开始学C++之构造函数与析构函数(二):初始化列表(const和引用成员)、拷贝构造函数
一.构造函数初始化列表 推荐在构造函数初始化列表中进行初始化 构造函数的执行分为两个阶段 初始化段 普通计算段 (一).对象成员及其初始化 C++ Code 1 2 3 4 5 6 7 8 9 1 ...
- stata
1.只打开部分变量: use var1 var2 using "C:\data\2014.dta" 2.打开部分样本(5~10个样本) use "C:\data\2014 ...
- Future 和 ExecutorCompletionService 对比和使用
当我们通过Executor提交一组并发执行的任务,并且希望在每一个任务完成后能立即得到结果,有两种方式可以采取: 方式一: 通过一个list来保存一组future,然后在循环中轮训这组future,直 ...
- Andrew Ng机器学习入门——线性回归
本人从2017年起,开始涉猎机器学习.作为入门,首先学习的是斯坦福大学Andrew Ng(吴恩达)教授的Coursera课程 2 单变量线性回归 线性回归属于监督学习(Supervise Learni ...
- 详解一下网络广告cpc、cpm、cpl、cpa、cps、cpr的计费方法是什么
CPC(Cost per click)按照 广告 点击数 计费 ,限定一个IP在24小时内只能点击一次.CPM(Cost per mille)按照广告显示次数来计算广告费,可在短时间内为 网站 带来巨 ...
- windows下运行hadoop2.7.2
1.下载hadoop-2.7.2.tar.gz 2.解压到D:\hadoop\ 3.配置HADOOP_HOME环境变量 4.将%HADOOP_HOME%\bin目录添加到path环境变量中 5.配置J ...
- 苹果也要开发AR眼镜,正与蔡司联手打造
近日,知名博主Robert Scoble在Facebook上称,苹果正在与德国卡尔蔡司公司合作研发一副增强现实智能眼镜,而且最快将在今年发布.据Scoble称,通过和蔡司的雇员在上周的CES展会上进行 ...
- JqGrid在行中自定义自己的东西
$.fn.fmatter.actions = function(cellval, opts) { function baseOption(obj) { return { url: obj.url || ...
- GTK+2.0学习——第一个GTK程序
#include <gtk/gtk.h> #include <stdio.h> #include <stdlib.h> /* *点击了关闭按钮之后的回调函数 *gt ...
题目链接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 不过还是大爆手速打了一通拿到首杀了嘻嘻 美滋滋辽 然 ...
I.JVM进程的生命周期 JVM实例的生命周期和java程序的生命周期保持一致,即一个新的程序启动则产生一个新的JVM进程实例,程序结束则JVM进程实例伴随着消失.那么程序启动和程序终止就是JVM实例 ...
一.构造函数初始化列表 推荐在构造函数初始化列表中进行初始化 构造函数的执行分为两个阶段 初始化段 普通计算段 (一).对象成员及其初始化 C++ Code 1 2 3 4 5 6 7 8 9 1 ...
1.只打开部分变量: use var1 var2 using "C:\data\2014.dta" 2.打开部分样本(5~10个样本) use "C:\data\2014 ...
当我们通过Executor提交一组并发执行的任务,并且希望在每一个任务完成后能立即得到结果,有两种方式可以采取: 方式一: 通过一个list来保存一组future,然后在循环中轮训这组future,直 ...
本人从2017年起,开始涉猎机器学习.作为入门,首先学习的是斯坦福大学Andrew Ng(吴恩达)教授的Coursera课程 2 单变量线性回归 线性回归属于监督学习(Supervise Learni ...
CPC(Cost per click)按照 广告 点击数 计费 ,限定一个IP在24小时内只能点击一次.CPM(Cost per mille)按照广告显示次数来计算广告费,可在短时间内为 网站 带来巨 ...
1.下载hadoop-2.7.2.tar.gz 2.解压到D:\hadoop\ 3.配置HADOOP_HOME环境变量 4.将%HADOOP_HOME%\bin目录添加到path环境变量中 5.配置J ...
近日,知名博主Robert Scoble在Facebook上称,苹果正在与德国卡尔蔡司公司合作研发一副增强现实智能眼镜,而且最快将在今年发布.据Scoble称,通过和蔡司的雇员在上周的CES展会上进行 ...
$.fn.fmatter.actions = function(cellval, opts) { function baseOption(obj) { return { url: obj.url || ...
#include <gtk/gtk.h> #include <stdio.h> #include <stdlib.h> /* *点击了关闭按钮之后的回调函数 *gt ...