HDU 5033 Building
来源:互联网 发布:淘宝推广软件有哪些 编辑:程序博客网 时间:2024/05/17 05:11
题目大意:给出n个高楼的位置(可看做垂直x轴的线段) 有q次查询 每次查询一个x坐标 求在此处的能看到天空的角度范围
由于查询次数q有10的5次方 n也有10的5次方 x坐标10的7次方 很难想到预先处理好 然后O(1)查询的处理方式 所以可以尝试用离线 预先把查询的坐标 以(x,0)存入 高楼以(x,h)来存
首先要以x排个序 首先 如果你每个查询点 左右的暴力找 这样肯定太慢 但你不难发现一条规律 每个点在右面找到的那个斜率最高点设为A(即从查询点来看 这个大楼是最高的)那么这个点有什么特征的 首先 很容易的推出 点A 右面比A低的肯定不行 同理A左面(和查询点之间)也不存在比A高的 当然这样还是不够的 因为极限数据 最高复杂度依然会T 所以我们继续推 A和查询点直接的点 应该是构成一条 x²一样曲线的(其实是折线) 这样才能做到在A点斜率最大 而A右面的点应该是 根号x曲线 一样的 这样 不难得到 A是一个凸包上的点 (如果这都没想到凸包 说明你没透彻理解凸包) 查询点加进来之后(从右往左扫时) A和查询点之间的点会被删掉 所以我们扫到每个查询点时 和凸包上的上一个点 计算一下即可 从左到右扫两遍 复杂度O(nlogn)
#include<iostream>#include<cstdio>#include<cstring>#include<cctype>#include<cmath>#include<vector>#include<queue>#include<map>#include<algorithm>#include<set>#define scnaf scanf#define cahr char#define bug puts("bugbugbug");using namespace std;typedef long long ll;const int mod=1000000007;const int maxn=2e5+500;const int inf=1e9+10000;#define pai acos(-1.0)double ans[maxn];int n;struct Point{ double x,y; int id; Point(double x=0,double y=0,int id=0):x(x),y(y),id(id) {}} p[maxn],ch[maxn];Point operator - (Point A,Point B){ return Point(A.x - B.x, A.y - B.y , 0);}bool operator < (const Point& a, const Point& b){ return a.x<b.x;}double Cross(Point A,Point B){ return A.x*B.y-A.y*B.x;}double jisuan(Point A,Point B){ return atan( fabs( (A.y-B.y) / (A.x-B.x) ) ) * 180 / pai;}bool cmp(Point A,Point B){ return A.x>B.x;}void go(){ sort(p,p+n); int m=0; for(int i=0; i<n; i++) { if(i&&p[i].x==p[i-1].x) { ans[p[i].id]=ans[p[i-1].id]; continue; } while(m>1 && Cross(ch[m-1]-ch[m-2] ,p[i]-ch[m-2]) >= 0) m--; if(p[i].id!=-1) { double now=jisuan(p[i],ch[m-1]); ans[p[i].id]-=now; } ch[m++]=p[i]; } m=0; for(int i=n-1; i>=0; i--) { if(i!=n-1&&p[i].x==p[i+1].x) { ans[p[i].id]=ans[p[i+1].id]; continue; } while(m>1 && Cross(p[i]-ch[m-2],ch[m-1]-ch[m-2]) >= 0) m--; if(p[i].id!=-1) { double now=jisuan(p[i],ch[m-1]); ans[p[i].id]-=now; } ch[m++]=p[i]; }}int main(){ int T_T,test=1; scanf("%d",&T_T); while(T_T--) { int q; scanf("%d",&n); for(int i=0; i<n; i++) { scanf("%lf%lf",&p[i].x,&p[i].y); p[i].id=-1; } scanf("%d",&q); for(int j=0; j<q; j++) { scanf("%lf",&p[n+j].x); p[n+j].y=0; p[n+j].id=j; ans[j]=180; } n+=q; go(); printf("Case #%d:\n",test++); for(int i=0; i<q; i++) printf("%.10f\n",ans[i]); }}
0 0
- HDU 5033 Building
- HDU - 5033 Building
- hdu-5033-Building
- HDU 5033 - Building
- hdu 5033 Building
- hdu 5033 Building
- hdu 5033 Building
- HDU 5033 Building
- HDU 5033 Building
- HDU 5033 Building
- HDU 5033 Building (单调栈)
- HDU 5033 Building 单调队列
- hdu 5033——Building
- 【HDU】5033 Building 单调栈
- hdu 5033 Building(斜率优化)
- HDU 5033 Building (单调栈)
- hdu 5033 Building 单调栈
- hdu 5033 Building(单调栈)
- ANDROID自定义视图——onLayout源码 流程 思路详解
- ubuntu中的命令行出现方块的问题
- 免费代理上网 在线网页代理 vpn
- Oracle DBA常用查询
- 数控玻璃异形磨边CAD/CAM系统开发
- HDU 5033 Building
- Android工程目录结构详解
- ListView下拉刷新实现排序
- ios开发文字排版,段落排版,富文本
- PAT 1091. Acute Stroke (30)
- 运放的差分运算放大
- 肾果手机App Store切换区域(无需Visa或者万事达)
- 使用epeg生成无压缩的缩略图
- 把数组排成最小的数