bzoj2829: Credit card convex hull (convex hull)

topic here

practice

//What's the matter lately.... the hands are cheap again and again.. it's a bit bad; _;

The idea is to find a convex hull of all the centers of the circles, plus the circumference of the circle.

Remember mistakes: 1. Pay attention to precision issues. 2. Note that 1 is not written as i.

code

#include<bits/stdc++.h>
#define rep(i,x,y) for (int i=(x);i<=(y);i++)
#define ll long long
#define ld long double
#define sqr(x) ((x)*(x))
using namespace std;
const ld pi=acos(-1);
const ld eps=1e-8;
#define N 100005
int n,m,top;ld A,B,R,ans=0;
struct node{ld x,y;node(){}node(ld x_,ld y_){x=x_,y=y_;}}a[N],stk[N];
node rot(node x,ld alp){return node(x.x*cos(alp)-x.y*sin(alp),x.y*cos(alp)+x.x*sin(alp));}//向量x逆时针旋转alp度
node operator + (node x,node y){return node(x.x+y.x,x.y+y.y);}
node operator - (node x,node y){return node(x.x-y.x,x.y-y.y);}
ld cross(node A,node B){return A.x*B.y-A.y*B.x;}
ld dot(node A){return sqrt(sqr(A.x)+sqr(A.y));}
ld getlen(node A){return dot(A);}
const bool cmp(const node x,const node y){
    if (fabs(cross(x-a[1],y-a[1]))<eps) return getlen(x-a[1])<getlen(y-a[1]);
    return cross(x-a[1],y-a[1])>0;
}
void graham(){
    rep (i,1,n) if (a[i].y<a[1].y||a[i].y==a[1].y&&a[i].x<a[1].x) swap(a[i],a[1]);
    sort(&a[2],&a[n+1],cmp);
    stk[1]=a[1];stk[2]=a[2];top=2;
    rep (i,3,n){
        while (top>1&&cross(stk[top]-stk[top-1],a[i]-stk[top-1])<=eps) top--;
        stk[++top]=a[i];
    }
}
int main(){
    double A_,B_,R_;
    scanf("%d%lf%lf%lf",&n,&A_,&B_,&R_);A=A_,B=B_,R=R_;A-=2*R;B-=2*R;
    rep (i,1,n){
        double x,y,alp;scanf("%lf%lf%lf",&x,&y,&alp);
        node tmp(x,y);
        a[++m].x=x-B/2.;a[m].y=y-A/2.;a[m]=tmp+rot(a[m]-tmp,alp);
        a[++m].x=x-B/2.;a[m].y=y+A/2.;a[m]=tmp+rot(a[m]-tmp,alp);
        a[++m].x=x+B/2.;a[m].y=y-A/2.;a[m]=tmp+rot(a[m]-tmp,alp);
        a[++m].x=x+B/2.;a[m].y=y+A/2.;a[m]=tmp+rot(a[m]-tmp,alp);
    }
    n=m;graham();ans=0;
    rep (i,1,top) ans+=getlen(stk[i%top+1]-stk[(i+1)%top+1]);
    ans+=pi*2*R;
    printf("%.2lf\n",(double)ans);
    return 0;
}

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325937035&siteId=291194637