hdu 5033——Building

来源:互联网 发布:sql气溶胶自动灭火装置 编辑:程序博客网 时间:2024/05/21 09:03

题意:一个城市在X轴上,有很多高大的建筑,人站在城市中,问能看到天的角度是多少

思路:从左往右维护一个单调栈,记录当前可以看到的最高的一个建筑。每到一个人的位置就能直接算。然后从右往左再来一遍

参考:http://blog.csdn.net/u011345136/article/details/39454537

代码如下:

#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<algorithm>using namespace std;const double pi=acos(-1);struct building{    double x;    int h;};bool operator < (const building &a,const building &b){    return a.x<b.x;}int n;building b[200005];int s[200005];int head=0;double ans[100005];bool check(building a,building b,building c){    if(c.h<0)    {        c.h=0;    }    return abs(a.h-c.h)*abs(c.x-b.x)>=abs(b.h-c.h)*abs(c.x-a.x);}int main(){//freopen("data.txt","r",stdin);    int T;    scanf("%d",&T);    int kase=0;    while(T--)    {        int n;        scanf("%d",&n);        for(int i=0;i<n;++i)        {            scanf("%lf%d",&b[i].x,&b[i].h);        }        int q;        scanf("%d",&q);        for(int i=0;i<q;++i)        {            scanf("%lf",&b[i+n].x);            b[n+i].h=-i;        }        sort(b,b+n+q);//        for(int i=0;i<n+q;++i)//        {//            cout<<b[i].x<<' '<<b[i].h<<endl;//        }        head=0;//        cout<<"zzzzzzzzzzzzzzzzzzzzzzzzz"<<endl;//        cout<<n<<' '<<q<<endl;        for(int i=0;i<n+q;++i)        {            if(b[i].h<=0)            {//                cout<<head<<endl;                while(head>1&&check(b[s[head-2]],b[s[head-1]],b[i]))                {                    head--;                }                ans[-b[i].h]=atan(b[s[head-1]].h/(b[i].x-b[s[head-1]].x));            }            else            {        //        cout<<"??"<<head<<endl;                while(head>0&&b[s[head-1]].h<b[i].h)head--;               while(head>1&&check(b[s[head-2]],b[s[head-1]],b[i]))                {                    head--;                }                s[head++]=i;            }        }        head=0;        for(int i=n+q-1;i>=0;--i)        {            if(b[i].h<=0)            {                while(head>1&&check(b[s[head-2]],b[s[head-1]],b[i]))                {                    head--;                }           //     cout<<b[s[head-1]].h<<' '<<(b[i].x-b[s[head-1]].x)<<endl;                ans[-b[i].h]+=atan(b[s[head-1]].h/(b[s[head-1]].x-b[i].x));            }            else            {              while(head>0&&b[s[head-1]].h<b[i].h)head--;               while(head>1&&check(b[s[head-2]],b[s[head-1]],b[i]))                {                    head--;                }                s[head++]=i;            }        }  //      cout<<ans[0]<<endl;        printf("Case #%d:\n",++kase);        printf("%.5lf\n",(pi-ans[0])*180/pi);        for(int i=1;i<q;++i)        {            printf("%.5lf\n",(pi-ans[i])*180/pi);        }     //   puts("");    }    return 0;}


0 0
原创粉丝点击