Building(单调栈+凸包)
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
将建筑物和人的位置从左到右排序,对于每个位置利用栈求一次人左边建筑物的凸包,找到一个最小的角度,然后对称一下,再找一个右边的建筑物的最小角度,两个角度加起来就是答案。
将人左边的建筑物从左到右扫描,下面两种情况会出栈:
- 栈顶元素楼高小于等于当前扫描到的楼高,因此这是一个单调的栈
- 栈顶两个楼顶所在直线的斜率 小于 栈顶的楼顶和当前楼顶所在直线的斜率(这里的斜率指的是绝对值),这保证了栈中所有楼顶的构成的曲线是个凸包
然后再求人的视线和竖直线的最小角度时,如果栈顶的楼的人的视线与水平线夹角 大于 栈中第二个楼所成的夹角,则出栈
代码:
#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
#include<queue>
#include<set>
#include<vector>
#include<map>
#include<cmath> const int maxn=1e5+;
typedef long long ll;
using namespace std;
const double pi = acos(-1.0);
pair<double, double> p[maxn];
pair<double, int> pos[maxn];
double ans[maxn];
int stack[maxn], n, Q; double slope(const int a, const int b)
{
return -(p[a].second - p[b].second) / (p[a].first - p[b].first);
} double angle(const int a, const int b)
{
return atan((pos[b].first - p[a].first) / p[a].second);
} void solve()
{
int j = , top = ;
for(int i = ; i < Q; ++i)
{
while(j < n && p[j].first < pos[i].first)
{
while(top > && p[stack[top]].second <= p[j].second) top--;
while(top >= && slope(stack[top], j) < slope(stack[top - ], stack[top])) top--;
stack[++top] = j;
j++;
}
while(top >= && angle(stack[top], i) > angle(stack[top - ], i)) top--;
ans[pos[i].second] += angle(stack[top], i);
}
} int main()
{
int T, kase;
scanf("%d", &T);
for(int kase = ; kase <= T; ++kase)
{
scanf("%d", &n);
for(int i = ; i < n; ++i)
scanf("%lf%lf", &p[i].first, &p[i].second);
sort(p, p + n); scanf("%d", &Q);
for(int i = ; i < Q; ++i)
{
scanf("%lf", &pos[i].first);
pos[i].second = i;
ans[i] = 0.0;
}
sort(pos, pos + Q);
solve();
reverse(p, p + n);
reverse(pos, pos + Q);
for(int i = ; i < n; ++i) p[i].first = -p[i].first;
for(int i = ; i < Q; ++i) pos[i].first = -pos[i].first;
solve();
printf("Case #%d:\n", kase);
for(int i = ; i < Q; ++i)
printf("%.10lf\n", ans[i]/pi*180.0);
}
return ;
}
Building(单调栈+凸包)的更多相关文章
- HDU 5033 Building(单调栈)
HDU 5033 Building(单调栈) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5033 Description Once upon a ti ...
- hdu 5033 Building (单调栈 或 暴力枚举 )
Description Once upon a time Matt went to a small town. The town was so small and narrow that he can ...
- HDU5033 building 单调栈+计算几何
正解:单调栈 解题报告: 哇生气辽QAQ本来打了半天feel good都快调出来了然后说换题了QAQ(所以可能那题的代码会过一阵子再放上来了QAQ 不过还是大爆手速打了一通拿到首杀了嘻嘻 美滋滋辽 然 ...
- HDU - 5033 Building (单调栈+倍增)
题意:有一排建筑,每座建筑有一定的高度,宽度可以忽略,求在某点的平地上能看到天空的最大角度. 网上的做法基本都是离线的...其实这道题是可以在线做的. 对于向右能看到的最大角度,从右往左倍增维护每个时 ...
- HDU 5033 Building(单调栈维护凸包)
盗张图:来自http://blog.csdn.net/xuechelingxiao/article/details/39494433 题目大意:有一排建筑物坐落在一条直线上,每个建筑物都有一定的高度, ...
- BZOJ_1007_ [HNOI2008]_水平可见直线_(单调栈+凸包)
描述 http://www.lydsy.com/JudgeOnline/problem.php?id=1007 给出一些直线,沿着y轴从上往下看,能看到多少条直线. 分析 由于直线相交,会遮挡住一些直 ...
- HDU5033 Building(单调栈)
题意是说在水平轴上有很多建筑物(没有宽度),知道每个建筑物的位置与高度.有m个查询,每次查询位置x所能看到的天空的角度. 方法是将建筑与查询一起排序,从左往右计算一遍,如果是建筑物,则比较最后两个(当 ...
- hdu5033 Building (单调栈+)
http://acm.hdu.edu.cn/showproblem.php?pid=5033 2014 ACM/ICPC Asia Regional Beijing Online B 1002 Bui ...
- CF535E Tavas and Pashmaks 单调栈、凸包
传送门 题意:有一场比赛,$N$个人参加.每个人有两种参数$a,b$,如果存在正实数$A,B$使得$\frac{A}{a_i} + \frac{B}{b_i}$在$i=x$处取得最大值(可以有多个最大 ...
随机推荐
- 实验05——java算术运算符减法
package cn.tedu.demo; import java.math.BigDecimal; /** * @author 赵瑞鑫 E-mail:1922250303@qq.com * @ver ...
- 物联网实验Arduino(1)
回顾 我们使用的平台: Arduino 入门实验1 眨眼睛 /* Blink Turns an LED on for one second, then off for one second, repe ...
- 学生成绩管理系统-JAVA语言测试
首先右键新建一个工程project 选择Java Project,单击next下一步 project命名为“学生成绩管理系统”,点击finish继续 右键src文件夹新建Package包,取名为te ...
- Linux 安装 PostgreSQL
Linux 安装 PostgreSQL CentOS 7 安装 PostgreSQL 10 步骤 官网安装步骤,选择服务器和数据库版本,会给出相应的安装命令 # 安装 yum install -y h ...
- FSAF
Feature Selective Anchor-Free Module for Single-Shot Object Detection https://zhuanlan.zhihu.com/p/5 ...
- 2020-07-02:在浏览器输入一个url后按回车,会发生什么?
福哥答案2020-07-02: 简单回答: 域名解析. 建立TCP连接. 请求. 处理. 响应. 释放TCP连接. 页面渲染. 中级回答: 域名解析 浏览器DNS缓存. 操作系统DNS缓存. 路由器缓 ...
- C#LeetCode刷题之#507-完美数(Perfect Number)
问题 该文章的最新版本已迁移至个人博客[比特飞],单击链接 https://www.byteflying.com/archives/3879 访问. 对于一个 正整数,如果它和除了它自身以外的所有正因 ...
- 从一次外卖到对oauth2.0的思考
别问oauth1.0哪去了,问就是不好讲. 1. 外卖并不好吃 今天下班得早,想吃顿好的,于是就点了一份外卖,过了一会儿,外卖到了,但是在小区大门被堵住了,我亲自远程开门后才能进来,又过了一会,被 ...
- JDK1.8源码学习-String-hashCode方法为什么选择数字31作为乘子
1. 背景 某天,我在写代码的时候,无意中点开了 String hashCode 方法.然后大致看了一下 hashCode 的实现,发现并不是很复杂.但是我从源码中发现了一个奇怪的数字,也就是本文的主 ...
- 【支付宝SDK】沙箱调试,以及遇到的坑
from rest_framework.views import APIView from alipay import AliPay, DCAliPay, ISVAliPay from django. ...