HDU 5033 Building(北京网络赛B题) 单调栈 找规律
做了三天,,,终于a了。。。
| 11724203 | 2014-09-25 09:37:44 | Accepted | 5033 | 781MS | 7400K | 4751 B | G++ | czy |
Building
Time Limit: 10000/5000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others) Total Submission(s): 1257 Accepted Submission(s): 358 Special Judge
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.
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).
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
101.3099324740
Case #2:
90.0000000000
Case #3:
78.6900675260
题意:
城市看做二维平面,建筑看做x轴上某个位置为端点的竖着的线段,(xi,hi)表示在x轴xi位置有个高为hi的建筑(线段)。有多次询问,每次问人在某个平地上(x,0)能看到天空的角度。
题解:
维护 相邻两建筑顶(xi,hi)的连线的斜率的绝对值上升 的单调栈。
先把建筑和queries的点全部弄到一起,按xi排个序。然后从左到右来一波得出在某个空地往左看看到最高的是哪个建筑,再反过来来一波。
先按从左到右的情况来说:
维护单调栈,栈里存的是之后的空地可能看到的建筑,容易知这是递减的单调栈。
再思考,如果:

则只用存两边的点,中间那3个肯定看不到了。
如果:

则都要存,因为往右走的时候走着走着,右边第二个就比右边第一个高了,走着走着右边第三个又比右边第二个高了……(这时pop掉栈顶
可见我们存的是相邻两建筑顶(xi,hi)的连线的斜率的绝对值上升 的单调栈。
每看到一个空地,把栈首的不够高的都pop到,只留下那个能看到的最高的,然后把这个建筑加入结果记录中。(记录从这个空地往左看看到的最高的是哪个建筑)
反过来再来一遍。
最后再对询问搞一搞,就完啦。
#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<string> #define N 100005
#define M 10000002
#define mod 10000007
//#define p 10000007
#define mod2 100000000
//#define ll long long
//#define LL long long
#define maxi(a,b) (a)>(b)? (a) : (b)
#define mini(a,b) (a)<(b)? (a) : (b) using namespace std; int T;
int n;
int q;
const double pi=*atan(1.0); typedef struct
{
double x;
double h;
double xie;
double xier;
}BB; BB b[N]; typedef struct
{
double x;
double l;
double r;
double ans;
int num;
}QQ; QQ Q[N]; bool cmp1(BB c,BB d)
{
return c.x<d.x;
} bool cmp2(QQ c,QQ d)
{
return c.x<d.x;
} bool cmp3(QQ c,QQ d)
{
return c.num<d.num;
} void ini()
{
int i;
scanf("%d",&n);
for(i=;i<=n;i++){
scanf("%lf%lf",&b[i].x,&b[i].h);
}
sort(b+,b++n,cmp1);
scanf("%d",&q);
for(i=;i<=q;i++){
scanf("%lf",&Q[i].x);
Q[i].num=i;
}
sort(Q+,Q++q,cmp2);
} void solvel()
{
stack <BB> LL;
int i,j; BB te;
double now;
b[].xie=-;
LL.push(b[]);
j=;
for(i=;i<=q;i++){
while(b[j].x<Q[i].x)
{
te=LL.top();
while(LL.size()!= && b[j].h>te.h)
{
LL.pop();
if(LL.size()==) break;
te=LL.top();
} if(LL.size()==){
b[j].xie=-;
LL.push(b[j]);
j++;
continue;
} now=(te.h-b[j].h)/(b[j].x-te.x);
while(LL.size()> && now<te.xie){
LL.pop(); te=LL.top();
now=(te.h-b[j].h)/(b[j].x-te.x);
if(LL.size()<=) break;
}
b[j].xie=now;
LL.push(b[j]);
j++;
} te=LL.top();
Q[i].l=te.h/(Q[i].x-te.x);
LL.pop();
if(LL.size()==){
LL.push(te);
continue;
}
BB pre1=LL.top();
double lte=pre1.h/(Q[i].x-pre1.x);
while(LL.size()!= && lte>Q[i].l)
{
te=pre1;
Q[i].l=lte;
LL.pop();
if(LL.size()==){
// LL.push(te);
break;
}
pre1=LL.top();
lte=pre1.h/(Q[i].x-pre1.x);
}
LL.push(te);
}
} void solver()
{
int i,j;
stack<BB> RR;
BB te;
double now;
b[n].xier=-;
RR.push(b[n]);
j=n-;
for(i=q;i>=;i--){
while(b[j].x>Q[i].x)
{
te=RR.top();
while(RR.size()!= && b[j].h>te.h)
{
RR.pop();
if(RR.size()==) break;
te=RR.top();
} if(RR.size()==){
b[j].xier=-;
RR.push(b[j]);
j--;
continue;
} now=(te.h-b[j].h)/(-b[j].x+te.x);
while(RR.size()> && now<te.xier){
RR.pop(); te=RR.top();
now=(te.h-b[j].h)/(-b[j].x+te.x);
if(RR.size()<=) break;
}
b[j].xier=now;
RR.push(b[j]);
j--;
} te=RR.top();
Q[i].r=te.h/(-Q[i].x+te.x);
RR.pop();
if(RR.size()==){
RR.push(te);
continue;
}
BB pre2=RR.top();
double rte=pre2.h/(-Q[i].x+pre2.x);
while(RR.size()!= && rte>Q[i].r)
{
te=pre2;
Q[i].r=rte;
RR.pop();
if(RR.size()==){
// LL.push(te);
break;
}
pre2=RR.top();
rte=pre2.h/(-Q[i].x+pre2.x);
}
RR.push(te);
}
} void solve()
{
for(int i=;i<=q;i++){
Q[i].ans=(pi-atan(Q[i].l)-atan(Q[i].r))*/pi;
}
} void out()
{
sort(Q+,Q++q,cmp3);
for(int i=;i<=q;i++){
printf("%.10f\n",Q[i].ans);
}
} int main()
{
//freopen("data.in","r",stdin);
//freopen("data.out","w",stdout);
scanf("%d",&T);
for(int cnt=;cnt<=T;cnt++)
// while(T--)
// while(scanf("%d%d",&n,&m)!=EOF)
{
// if(n==0 && m==0) break;
printf("Case #%d:\n",cnt);
ini();
solvel();
solver();
solve();
out();
} return ;
}
HDU 5033 Building(北京网络赛B题) 单调栈 找规律的更多相关文章
- 2015北京网络赛 H题 Fractal 找规律
Fractal Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://hihocoder.com/contest/acmicpc2015beijingo ...
- 2019南昌网络赛-I(单调栈+线段树)
题目链接:https://nanti.jisuanke.com/t/38228 题意:定义一段区间的值为该区间的和×该区间的最小值,求给定数组的最大的区间值. 思路:比赛时还不会线段树,和队友在这题上 ...
- 2015北京网络赛 G题 Boxes bfs
Boxes Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://hihocoder.com/contest/acmicpc2015beijingonl ...
- (中等) Hiho 1232 Couple Trees(15年北京网络赛F题),主席树+树链剖分。
"Couple Trees" are two trees, a husband tree and a wife tree. They are named because they ...
- HDU 6205 2017沈阳网络赛 思维题
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6205 题意:给你n堆牌,原本每一堆的所有牌(a[i]张)默认向下,每次从第一堆开始,将固定个数的牌(b ...
- ACM-ICPC 2018北京网络赛-A题 Saving Tang Monk II-优先队列
做法:优先队列模板题,按步数从小到大为优先级,PASS掉曾经以相同氧气瓶走过的地方就好了 题目1 : Saving Tang Monk II 时间限制:1000ms 单点时限:1000ms 内存限制: ...
- hdu 5442 (ACM-ICPC2015长春网络赛F题)
题意:给出一个字符串,长度是2*10^4.将它首尾相接形成环,并在环上找一个起始点顺时针或逆时针走一圈,求字典序最大的走法,如果有多个答案则找起始点最小的,若起始点也相同则选择顺时针. 分析:后缀数组 ...
- hihoCoder #1388 : Periodic Signal ( 2016 acm 北京网络赛 F题)
时间限制:5000ms 单点时限:5000ms 内存限制:256MB 描述 Profess X is an expert in signal processing. He has a device w ...
- hihocoder 1236(2015北京网络赛 J题) 分块bitset乱搞题
题目大意: 每个人有五门课成绩,初始给定一部分学生的成绩,然后每次询问给出一个学生的成绩,希望知道在给定的一堆学生的成绩比这个学生每门都低或者相等的人数 因为强行要求在线查询,所以题目要求,每次当前给 ...
随机推荐
- selenium-浏览器操作方法
前戏 浏览器都有哪些方法呢?最大化,设置浏览器窗口的大小,刷新,前进,后退等等,让我们来一一介绍 获取网站titie from selenium import webdriver from time ...
- 【C语言项目】贪吃蛇游戏(下)
目录 00. 目录 07. 游戏逻辑 7.5 按下ESC键结束游戏 7.6 判断是否撞到墙 7.7 判断是否咬到自己 08. 游戏失败界面设计 8.1 游戏失败界面边框设计 8.2 撞墙失败界面 8. ...
- win7旗舰版下配置IIS服务器
选择上述的插件后,Windows 需要更新一段时间,并重启电脑 测试是否安装成功:http://localhost 注意:默认端口号是 80,不能和tomcat 的 80 端口同时重启 常 ...
- Bootsrtap 面包屑导航(Breadcrums)
Bootstrap面包屑导航是一种基于网站层次信息显示的方式.以博客为例,面包屑导航可以显示发布日期,类别或标签,它们表示当前页面在导航层次结构内的位置. Bootstrap面包屑导航其实是一个简单的 ...
- iOS7.1企业版发布后用户通过sarafi浏览器安装无效的解决方案
关于iOS7.1企业版发布后,用户通过sarafi浏览器安装无效的解决方案: 通过测试,已经完美解决. 方案一: iOS7.1企业应用无法安装应用程序 因为证书无效的解决方案 http://blog. ...
- 调用 C 动态库
调用 C 动态库 由 王巍 (@ONEVCAT) 发布于 2015/11/04 C 是程序世界的宝库,在我们面向的设备系统中,也内置了大量的 C 动态库帮助我们完成各种任务.比如涉及到压缩的话我们很可 ...
- MFC学习小结
2019/1/13 视频来源 一. MFC框架中一些重要的函数 1. InitInstance函数 应用程序类的一个虚函数,MFC应用程序的入口.初始化的作用. 2. PreCreateWindo ...
- UVa-156-反片语
这题比较精妙的是,我们对于单词重排,实际上是进行了标准化的处理,即按照字典序排序. 这样的话,就很方便地处理了单词的重排问题,我们不需要使用全排列函数进行排列尝试,我们直接化简为一,然后进行比较就可以 ...
- Django_外键查询和反查询
一.ForeignKey @property装饰器的作用是返回一个属性特性,在数据库中也有一些小技巧可以拿来用,比如今天要写的外键查询和反向查询的内容. from django.db import m ...
- 关于PHP版本比较函数version_compare的问题
$version1="v4.0"; $version2="v4.0.0"; print_r(version_compare($version1,$version ...