HDU 5033 Building
2014-10-02 21:43
260 查看
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5033
解题报告:在一条x轴上有n个建筑物,每个建筑物有一个高度h,然后现在有q次查询,查询的内容是假设有一个人站在xi这个位置,问他看天空的视角是多大,用角度表示。
数据量都比较大,n和q都是10^5,但因为q次都是查询操作,并没有要求在线更新和查询,所以我们想到用离线算法,先把全部的输入接收,然后离线算出最后打出结果。
这题的思路是把所有的建筑物按照高度从大到小排序,然后所有的查询按照x从小到大排序,然后用建筑物去更新每个人一个建筑物只能更新一个人的一边的角度,当不能更新时,则推出此次更新,取出下一个建筑物来更新所有的人。理论上这样到后面每个建筑物可以更新的人的数量会越来越少,所以不会超时。
View Code
解题报告:在一条x轴上有n个建筑物,每个建筑物有一个高度h,然后现在有q次查询,查询的内容是假设有一个人站在xi这个位置,问他看天空的视角是多大,用角度表示。
数据量都比较大,n和q都是10^5,但因为q次都是查询操作,并没有要求在线更新和查询,所以我们想到用离线算法,先把全部的输入接收,然后离线算出最后打出结果。
这题的思路是把所有的建筑物按照高度从大到小排序,然后所有的查询按照x从小到大排序,然后用建筑物去更新每个人一个建筑物只能更新一个人的一边的角度,当不能更新时,则推出此次更新,取出下一个建筑物来更新所有的人。理论上这样到后面每个建筑物可以更新的人的数量会越来越少,所以不会超时。
#include<cstdio> #include<iostream> #include<algorithm> #include<cstring> #include<cmath> using namespace std; const int maxn = 100005; const double PI = acos(-1.0); struct node { double x,h; }building[maxn]; struct Node { double x,left,right; int ci; }men[maxn]; bool cmpb(node a,node b) { if(a.h != b.h) return a.h > b.h; else return a.x < b.x; } bool cmpm(Node a,Node b) { return a.x < b.x; } bool cmpci(Node a,Node b) { return a.ci < b.ci; } int find(double x,int l,int r) { while(l < r) { int mid = (l + r) >> 1; if(men[mid].x >= x) r = mid; else l = mid + 1; } return l; } double zhuanhua(double a,double b) { double temp = PI - (atan(a) + atan(b)); temp = 180.0 * temp / PI; return temp; } int main() { int T,kase = 1,n,q; scanf("%d",&T); while(T--) { scanf("%d",&n); for(int i = 1;i <= n;++i) scanf("%lf%lf",&building[i].x,&building[i].h); scanf("%d",&q); for(int i = 1;i <= q;++i) { scanf("%lf",&men[i].x); men[i].ci = i; men[i].left = men[i].right = 0; } sort(building+1,building+n+1,cmpb); sort(men+1,men+q+1,cmpm); for(int i = 1;i <= n;++i) { int m = find(building[i].x,1,q+1); //第 m 个是第一个大于这个 x 的位置 // printf("m = %d\n",m); //////现在先往右扫 int r = m; while(r <= q) { double k = building[i].h / (men[r].x - building[i].x); if(k > men[r].right) men[r++].right = k; else break; } int l = m - 1; while(l >= 1) { double k = building[i].h / (building[i].x - men[l].x); if(k > men[l].left) men[l--].left = k; else break; } } sort(men+1,men+q+1,cmpci); printf("Case #%d:\n",kase++); for(int i = 1;i <= q;++i) printf("%.10lf\n",zhuanhua(men[i].left,men[i].right)); } return 0; } /* 33 5 1 2 3 3 5 1 7 4 9 2 4 2 4 6 8 */
View Code
相关文章推荐
- hdu 5033 ( Building ) 单调栈
- hdu 5033 Building
- HDU 5033 Building
- HDU 5033 Building --离线+单调栈
- hdu 5033 Building 几何+单调栈
- hdu-5033-Building
- HDU 5033 Building(类凸包+向量叉积的应用)
- HDU 5033 Building(DP,2014北京网络赛1002)
- Hdu 5033 Building(2014 ACM/ICPC Asia Regional Beijing Online1002) [几何]
- hdu 5033 Building(北京网络赛)
- HDU 5033 Building
- hdu 5033——Building
- HDU 5033---Building(单调栈)
- HDU 5033-B - Building-维护凸包-单调栈
- HDU 5033 Building 单调队列
- HDU 5033 Building (单调栈维护凸包)
- HDU 5033 Building(2014北京网络赛 单调栈+几何)
- hdu 5033 Building 2014 ACM/ICPC Asia Regional Beijing Online
- HDU 5033 Building(单调栈, 类凸包)
- HDU 5033 Building 解题报告(维护凸包)