码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 5033 Building

时间:2014-10-02 22:37:43      阅读:334      评论:0      收藏:0      [点我收藏+]

标签:style   blog   http   color   io   os   ar   for   数据   

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5033

解题报告:在一条x轴上有n个建筑物,每个建筑物有一个高度h,然后现在有q次查询,查询的内容是假设有一个人站在xi这个位置,问他看天空的视角是多大,用角度表示。

数据量都比较大,n和q都是10^5,但因为q次都是查询操作,并没有要求在线更新和查询,所以我们想到用离线算法,先把全部的输入接收,然后离线算出最后打出结果。

这题的思路是把所有的建筑物按照高度从大到小排序,然后所有的查询按照x从小到大排序,然后用建筑物去更新每个人一个建筑物只能更新一个人的一边的角度,当不能更新时,则推出此次更新,取出下一个建筑物来更新所有的人。理论上这样到后面每个建筑物可以更新的人的数量会越来越少,所以不会超时。

bubuko.com,布布扣
  1 #include<cstdio>
  2 #include<iostream>
  3 #include<algorithm>
  4 #include<cstring>
  5 #include<cmath> 
  6 using namespace std;
  7 const int maxn = 100005;
  8 const double PI = acos(-1.0);
  9 struct node
 10 {
 11     double x,h;
 12 }building[maxn];
 13 struct Node
 14 {
 15     double x,left,right;
 16     int ci;
 17 }men[maxn];
 18 bool cmpb(node a,node b)
 19 {
 20     if(a.h != b.h)
 21     return a.h > b.h; 
 22     else return a.x  < b.x;
 23 }
 24 bool cmpm(Node a,Node b)
 25 {
 26     return a.x < b.x;
 27 }
 28 bool cmpci(Node a,Node b)
 29 {
 30     return a.ci < b.ci;
 31 }
 32 int find(double x,int l,int r)
 33 {
 34     while(l < r)
 35     {
 36         int mid = (l + r) >> 1;
 37         if(men[mid].x >= x)
 38         r = mid;
 39         else l = mid + 1;
 40     }
 41     return l;
 42 }
 43 
 44 double zhuanhua(double a,double b)
 45 {
 46     double temp = PI - (atan(a) + atan(b));
 47     temp = 180.0 * temp / PI;
 48     return temp;
 49 }
 50 int main()
 51 {
 52     int T,kase = 1,n,q;
 53     scanf("%d",&T);
 54     while(T--)
 55     {
 56         scanf("%d",&n);
 57         for(int i = 1;i <= n;++i)
 58         scanf("%lf%lf",&building[i].x,&building[i].h);    
 59         scanf("%d",&q);
 60         for(int i  = 1;i <= q;++i)
 61         {
 62             scanf("%lf",&men[i].x);
 63             men[i].ci = i;
 64             men[i].left = men[i].right = 0;
 65         }
 66         sort(building+1,building+n+1,cmpb);
 67         sort(men+1,men+q+1,cmpm);
 68         for(int i = 1;i <= n;++i)
 69         {
 70             int m = find(building[i].x,1,q+1);    //第 m 个是第一个大于这个 x 的位置
 71     //        printf("m = %d\n",m);
 72             //////现在先往右扫
 73             int r = m;
 74             while(r <= q)
 75             {  
 76                 double k = building[i].h / (men[r].x - building[i].x);
 77                 if(k > men[r].right) 
 78                 men[r++].right = k;
 79                 else break;
 80             }
 81             int l = m - 1;
 82             while(l >= 1)
 83             {
 84                 double k = building[i].h / (building[i].x - men[l].x);
 85                 if(k > men[l].left)
 86                 men[l--].left = k;
 87                 else break;
 88             }
 89         }
 90         sort(men+1,men+q+1,cmpci);
 91         printf("Case #%d:\n",kase++);
 92         for(int i = 1;i <= q;++i)
 93             printf("%.10lf\n",zhuanhua(men[i].left,men[i].right));
 94     }
 95     return 0;
 96 }
 97 /*
 98 33
 99 5
100 1 2
101 3 3
102 5 1
103 7 4
104 9 2
105 4
106 2
107 4
108 6
109 8
110 */
View Code

 

HDU 5033 Building

标签:style   blog   http   color   io   os   ar   for   数据   

原文地址:http://www.cnblogs.com/xiaxiaosheng/p/4004495.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!