HDU - 5033 Building

题目

HDU - 5033 Building

做法

其实就是维护一个上凸壳

因为下凸时的右端点是不会起到贡献的作用

计算几何要注意的点(还是太弱了,dalao请略过):
\(atan()\):通过比值计算弧度
\(1rad=\frac{180^{o}}{\pi}\)

My complete code

#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<string>
#include<vector>
#include<ctime>
#include<stack>
#include<cmath>
using namespace std;
typedef long long LL;
const LL maxn=300000;
const double inf=10000000.0;
const double Pi=acos(-1.0);
inline LL Read(){
    LL x(0),f(1); char c=getchar();
    while(c<'0'||c>'9'){
        if(c=='-')f=-1;c=getchar();
    }
    while(c>='0'&&c<='9')
        x=(x<<3)+(x<<1)+c-'0',c=getchar();
    return x*f;
}
LL n,m,T,cas;
double ans[maxn];
struct node{
    double x,y;
    LL id;
    node(){};
    node(double xx,double yy,LL idd):x(xx),y(yy),id(idd){};
    bool operator <(const node &b)const{
        return x<b.x;
    }
    node operator -(const node &b)const{
        return node(x-b.x,y-b.y,0);
    }
}q[maxn];
node sta[maxn];

inline bool compare(node a,node b){
    return a.y*b.x-b.y*a.x>0;
} 
inline bool Check(node a,node b,node c){
    return compare(a-c,c-b);
}
inline double Calc(node a,node b){
    return atan((b.x-a.x)/a.y);
}
inline void Solve(){
    LL top=0;
    for(LL i=1;i<=n;++i){
        if(q[i].id){
            while(top>=2&&Check(sta[top-1],sta[top],q[i]))
                --top;
            ans[q[i].id]+=Calc(sta[top],q[i]);
        }else{
            while(top&&sta[top].y<=q[i].y)
                --top;
            while(top>=2&&Check(sta[top-1],sta[top],q[i]))
                --top; 
            sta[++top]=q[i];
        }
    }
}
int main(){
    T=Read();
    while(T--){
        n=Read();
        for(LL i=1;i<=n;++i){
            scanf("%lf%lf",&q[i].x,&q[i].y);
            q[i].id=0;
        }
        m=Read();
        for(LL i=1;i<=m;++i){
            scanf("%lf",&q[++n].x),
            q[n].y=0;
            q[n].id=i;
        }
        sort(q+1,q+1+n),
        memset(ans,0,sizeof(ans));
        Solve();
        reverse(q+1,q+1+n);
        for(LL i=1;i<=n;++i)
            q[i].x=inf-q[i].x;
        Solve();
        printf("Case #%lld:\n",++cas);
        for(LL i=1;i<=m;++i)
            printf("%.10lf\n",ans[i]*180/Pi);
    }
    return 0;
}/*
*/

猜你喜欢

转载自www.cnblogs.com/y2823774827y/p/10284382.html
今日推荐