zoukankan      html  css  js  c++  java
  • 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

    Problem Description
       Once upon a time Matt went to a small town. The town was so small and narrow that he can regard the town as a pivot. There were some skyscrapers in the town, each located at position xi with its height hi. All skyscrapers located in different place. The skyscrapers had no width, to make it simple. As the skyscrapers were so high, Matt could hardly see the sky.Given the position Matt was at, he wanted to know how large the angle range was where he could see the sky. Assume that Matt's height is 0. It's guaranteed that for each query, there is at least one building on both Matt's left and right, and no building locate at his position.
     
    Input
       The first line of the input contains an integer T, denoting the number of testcases. Then T test cases follow.
       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.
     
    Output
       For each test case, first output one line "Case #x:", where x is the case number (starting from 1).
       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).
     
    Sample Input
    3 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
     
    Sample Output
    Case #1: 101.3099324740 Case #2: 90.0000000000 Case #3: 78.6900675260
     
    Source
     
    Recommend
    hujie   |   We have carefully selected several similar problems for you:  5041 5040 5039 5038 5036 
     
     

    题意:

    城市看做二维平面,建筑看做x轴上某个位置为端点的竖着的线段,(xi,hi)表示在x轴xi位置有个高为hi的建筑(线段)。有多次询问,每次问人在某个平地上(x,0)能看到天空的角度。

    题解:

    维护 相邻两建筑顶(xi,hi)的连线的斜率的绝对值上升 的单调栈。

    先把建筑和queries的点全部弄到一起,按xi排个序。然后从左到右来一波得出在某个空地往左看看到最高的是哪个建筑,再反过来来一波。

    先按从左到右的情况来说:

    维护单调栈,栈里存的是之后的空地可能看到的建筑,容易知这是递减的单调栈。

    再思考,如果:

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

    如果:

    则都要存,因为往右走的时候走着走着,右边第二个就比右边第一个高了,走着走着右边第三个又比右边第二个高了……(这时pop掉栈顶

    可见我们存的是相邻两建筑顶(xi,hi)的连线的斜率的绝对值上升 的单调栈

    每看到一个空地,把栈首的不够高的都pop到,只留下那个能看到的最高的,然后把这个建筑加入结果记录中。(记录从这个空地往左看看到的最高的是哪个建筑)

    反过来再来一遍。

    最后再对询问搞一搞,就完啦。

      1 #include<iostream>
      2 #include<cstring>
      3 #include<cstdlib>
      4 #include<cstdio>
      5 #include<algorithm>
      6 #include<cmath>
      7 #include<queue>
      8 #include<map>
      9 #include<stack>
     10 #include<string>
     11 
     12 #define N 100005
     13 #define M 10000002
     14 #define mod 10000007
     15 //#define p 10000007
     16 #define mod2 100000000
     17 //#define ll long long
     18 //#define LL long long
     19 #define maxi(a,b) (a)>(b)? (a) : (b)
     20 #define mini(a,b) (a)<(b)? (a) : (b)
     21 
     22 using namespace std;
     23 
     24 int T;
     25 int n;
     26 int q;
     27 const double pi=4*atan(1.0);
     28 
     29 typedef struct
     30 {
     31     double x;
     32     double h;
     33     double xie;
     34     double xier;
     35 }BB;
     36 
     37 BB b[N];
     38 
     39 typedef struct
     40 {
     41     double x;
     42     double l;
     43     double r;
     44     double ans;
     45     int num;
     46 }QQ;
     47 
     48 QQ Q[N];
     49 
     50 bool cmp1(BB c,BB d)
     51 {
     52     return c.x<d.x;
     53 }
     54 
     55 bool cmp2(QQ c,QQ d)
     56 {
     57     return c.x<d.x;
     58 }
     59 
     60 bool cmp3(QQ c,QQ d)
     61 {
     62     return c.num<d.num;
     63 }
     64 
     65 void ini()
     66 {
     67     int i;
     68     scanf("%d",&n);
     69     for(i=1;i<=n;i++){
     70         scanf("%lf%lf",&b[i].x,&b[i].h);
     71     }
     72     sort(b+1,b+1+n,cmp1);
     73     scanf("%d",&q);
     74     for(i=1;i<=q;i++){
     75         scanf("%lf",&Q[i].x);
     76         Q[i].num=i;
     77     }
     78     sort(Q+1,Q+1+q,cmp2);
     79 }
     80 
     81 
     82 void solvel()
     83 {
     84     stack <BB> LL;
     85     int i,j;
     86 
     87     BB te;
     88     double now;
     89     b[1].xie=-1;
     90     LL.push(b[1]);
     91     j=2;
     92     for(i=1;i<=q;i++){
     93         while(b[j].x<Q[i].x)
     94         {
     95             te=LL.top();
     96             while(LL.size()!=0 && b[j].h>te.h)
     97             {
     98                 LL.pop();
     99                 if(LL.size()==0) break;
    100                 te=LL.top();
    101             }
    102 
    103             if(LL.size()==0){
    104                 b[j].xie=-1;
    105                 LL.push(b[j]);
    106                 j++;
    107                 continue;
    108             }
    109 
    110             now=(te.h-b[j].h)/(b[j].x-te.x);
    111             while(LL.size()>1 && now<te.xie){
    112                 LL.pop();
    113 
    114                 te=LL.top();
    115                 now=(te.h-b[j].h)/(b[j].x-te.x);
    116                 if(LL.size()<=1) break;
    117             }
    118             b[j].xie=now;
    119             LL.push(b[j]);
    120             j++;
    121         }
    122 
    123         te=LL.top();
    124         Q[i].l=te.h/(Q[i].x-te.x);
    125         LL.pop();
    126         if(LL.size()==0){
    127             LL.push(te);
    128             continue;
    129         }
    130         BB pre1=LL.top();
    131         double lte=pre1.h/(Q[i].x-pre1.x);
    132         while(LL.size()!=0 && lte>Q[i].l)
    133         {
    134             te=pre1;
    135             Q[i].l=lte;
    136             LL.pop();
    137             if(LL.size()==0){
    138                // LL.push(te);
    139                 break;
    140             }
    141             pre1=LL.top();
    142             lte=pre1.h/(Q[i].x-pre1.x);
    143         }
    144         LL.push(te);
    145     }
    146 }
    147 
    148 
    149 void solver()
    150 {
    151     int i,j;
    152     stack<BB> RR;
    153     BB te;
    154     double now;
    155     b[n].xier=-1;
    156     RR.push(b[n]);
    157     j=n-1;
    158     for(i=q;i>=1;i--){
    159         while(b[j].x>Q[i].x)
    160         {
    161             te=RR.top();
    162             while(RR.size()!=0 && b[j].h>te.h)
    163             {
    164                 RR.pop();
    165                 if(RR.size()==0) break;
    166                 te=RR.top();
    167             }
    168 
    169             if(RR.size()==0){
    170                 b[j].xier=-1;
    171                 RR.push(b[j]);
    172                 j--;
    173                 continue;
    174             }
    175 
    176             now=(te.h-b[j].h)/(-b[j].x+te.x);
    177             while(RR.size()>1 && now<te.xier){
    178                 RR.pop();
    179 
    180                 te=RR.top();
    181                 now=(te.h-b[j].h)/(-b[j].x+te.x);
    182                 if(RR.size()<=1) break;
    183             }
    184             b[j].xier=now;
    185             RR.push(b[j]);
    186             j--;
    187         }
    188 
    189         te=RR.top();
    190         Q[i].r=te.h/(-Q[i].x+te.x);
    191         RR.pop();
    192         if(RR.size()==0){
    193             RR.push(te);
    194             continue;
    195         }
    196         BB pre2=RR.top();
    197         double rte=pre2.h/(-Q[i].x+pre2.x);
    198         while(RR.size()!=0 && rte>Q[i].r)
    199         {
    200             te=pre2;
    201             Q[i].r=rte;
    202             RR.pop();
    203             if(RR.size()==0){
    204                // LL.push(te);
    205                 break;
    206             }
    207             pre2=RR.top();
    208             rte=pre2.h/(-Q[i].x+pre2.x);
    209         }
    210         RR.push(te);
    211     }
    212 }
    213 
    214 void solve()
    215 {
    216     for(int i=1;i<=q;i++){
    217         Q[i].ans=(pi-atan(Q[i].l)-atan(Q[i].r))*180/pi;
    218     }
    219 }
    220 
    221 void out()
    222 {
    223     sort(Q+1,Q+1+q,cmp3);
    224     for(int i=1;i<=q;i++){
    225         printf("%.10f
    ",Q[i].ans);
    226     }
    227 }
    228 
    229 int main()
    230 {
    231     //freopen("data.in","r",stdin);
    232     //freopen("data.out","w",stdout);
    233     scanf("%d",&T);
    234     for(int cnt=1;cnt<=T;cnt++)
    235    // while(T--)
    236    // while(scanf("%d%d",&n,&m)!=EOF)
    237     {
    238       //  if(n==0 && m==0) break;
    239         printf("Case #%d:
    ",cnt);
    240         ini();
    241         solvel();
    242         solver();
    243         solve();
    244         out();
    245     }
    246 
    247     return 0;
    248 }
  • 相关阅读:
    Caused by: java.lang.ClassNotFoundException: org.hibernate.annotations.common.reflection.MetadataPro
    Caused by: java.lang.ClassNotFoundException: org.dom4j.DocumentException
    让你的C程序更有效率的10种方法
    c++效率浅析
    Caused by: java.lang.ClassNotFoundException: org.hibernate.engine.FilterDefinition
    Caused by: java.lang.ClassNotFoundException: javax.transaction.TransactionManager
    Caused by: java.lang.NoClassDefFoundError: org/hibernate/cfg/Configuration
    Caused by: java.lang.ClassNotFoundException: org.aspectj.weaver.reflect.ReflectionWorld$ReflectionWo
    Caused by: java.lang.ClassNotFoundException: org.jbpm.pvm.internal.processengine.SpringHelper
    Caused by: java.lang.ClassNotFoundException: org.aopalliance.intercept.MethodInterceptor
  • 原文地址:https://www.cnblogs.com/njczy2010/p/3992105.html
Copyright © 2011-2022 走看看