HDU 5033 Building (維護單調棧)

來源:互聯網
上載者:User

標籤:style   blog   http   color   io   os   ar   for   sp   

題目連結

題意:n個建築物,Q條詢問,問所在的位置,看到天空的角度是多少,每條詢問的位置左右必定是有建築物的。

思路 : 維護一個單調棧,將所有的建築物和所有的人都放到一起開始算就行,每加入一個人,就維護棧裡的建築物的高度,也就是說這個人所能夠看到的建築物時在棧裡的,但是這個人看不到的就刪掉,例如,中間三個點可以刪掉了,因為角度問題中間三個是看不到的,所以不會影響最終求得角度

還有一種情況,就是下述的情況,不停的維護單調棧,人站在不同的地方角度也是不一樣的。

維護的是相鄰兩建築頂(xi,hi)的連線的斜率的絕對值上升 的單調棧。

從左往右一遍,右往左一遍。

是代碼中judge函數的圖,要判斷是否建築物被另一建築物遮擋。

 1 #include <stdio.h> 2 #include <string.h> 3 #include <math.h> 4 #include <iostream> 5 #include <stack> 6 #include <algorithm> 7 #define PI acos(-1.0) 8 using namespace std ; 9 10 struct node11 {12     int pos ;13     int height ;14     bool operator <(const node &a)const15     {16         return pos < a.pos ;17     }18 } p[401210],stk[401210];19 double sh[401010] ;20 int T,n,q;21 22 23 int judge(node &a,node &b,node c){//判斷在c處的視野中,a建築物是否能夠在c處沒有被b建築物擋住24     if(c.height <= 0) c.height = 0 ;25     return (long long)(a.height-c.height)*(c.pos-b.pos) >= (long long)(b.height-c.height)*(c.pos-a.pos) ;26 }27 28 double angle(node a,node b)//求a建築物與b處所成角的大小29 {30     return atan((double)(b.pos-a.pos)/(double)(a.height)) ;31 }32 void solve()33 {34     int top = 0 ;35     for(int i = 0 ; i < n+q ; i ++){36         if(p[i].height <= 0){//是人的地方37             while(top >= 2 && judge(stk[top-2],stk[top-1],p[i])) top -- ;//如果top-1擋不住top-2的話,說明top-1在角度貢獻上沒什麼用38             sh[-p[i].height] += angle(stk[top-1],p[i]) ;39         }40         else41         {42             while(top && stk[top-1].height <= p[i].height) top-- ;//如果棧頂元素沒有新的這個高,那麼肯定會被擋到,所以沒有用刪掉43             while(top >= 2 && judge(stk[top-2],stk[top-1],p[i])) top--;//把這三個建築物的最高點相連,若是凹的,中間那個肯定會被擋到,刪掉44             stk[top++] = p[i] ;45         }46     }47 }48 int main()49 {50     scanf("%d",&T) ;51     int casee = 1 ;52     while(T--)53     {54         scanf("%d",&n) ;55         for(int i = 0 ; i < n ; i++)56         {57             scanf("%d %d",&p[i].pos,&p[i].height) ;58         }59         scanf("%d",&q) ;60         for(int i = 0 ; i < q ; i++)61         {62             scanf("%d",&p[i+n].pos) ;63             p[i+n].height = -i ;//輸出方便64         }65         memset(sh,0,sizeof(sh)) ;66         sort(p,p+n+q) ;67         solve() ;68         reverse(p,p+n+q) ;69         for(int i = 0 ; i < n+q ; i++)//把後邊的全部都移到前邊去,與上邊的統一,方便調用函數70             p[i].pos = 10000000 -p[i].pos ;71         solve() ;72         printf("Case #%d:\n",casee++) ;73         for(int i = 0 ; i < q ; i++){74             printf("%.10lf\n",sh[i]*180/PI) ;//角度與弧度的轉化75         }76     }77     return 0 ;78 }
View Code

 

HDU 5033 Building (維護單調棧)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.