BZOJ 2829 信用卡凸包 ——计算几何

凸包裸题

#include <map>
#include <cmath>
#include <queue>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
#define F(i,j,k) for (int i=j;i<=k;++i)
#define D(i,j,k) for (int i=j;i>=k;--i)
#define ll long long
#define eps 1e-8
#define mp make_pair
 
const double pi=acos(-1.0);
 
struct Vector{
    double x,y;
    void print()
    {
        printf("Vector (%.3f,%.3f)\n",x,y);
    }
};
struct Point{
    double x,y;
    void print()
    {
        printf("Point (%.3f,%.3f)\n",x,y);
    }
};
 
double operator * (Vector a,Vector b)
{return a.x*b.y-a.y*b.x;}
 
Point operator + (Point a,Vector b)
{Point ret;ret.x=a.x+b.x;ret.y=a.y+b.y;return ret;}
 
Vector operator - (Point a,Point b)
{Vector ret;ret.x=a.x-b.x;ret.y=a.y-b.y;return ret;}
 
double dist(Point a,Point b)
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
 
Vector Turn(Vector a,double b)
{
    Vector ret;
//  printf("Turn : \n");
//  a.print(); printf("in %.6f\n",b/pi*180);
    ret.x=a.x*cos(b)-a.y*sin(b);
    ret.y=a.y*cos(b)+a.x*sin(b);
//  ret.print();
    return ret;
}
 
int n,top=0,cnt=0;
double a,b,r,x,y,theta,ans=0;
Vector v[4];
int mov[4][2]={{1,1},{1,-1},{-1,1},{-1,-1}};
Point p[500005];
Point sta[500005];
 
bool cmp(Point a,Point b)
{
    return fabs(a.x-b.x)<eps?a.y<b.y:a.x<b.x;
}
 
void Andrew()
{
    cnt=0;
    sort(p+1,p+top+1,cmp);
//  F(i,1,top) p[i].print();
    sta[++cnt]=p[1];
    F(i,2,top)
    if (fabs(p[i].x-p[i-1].x)>eps||fabs(p[i].y-p[i-1].y)>eps){
//      printf("Add : ");p[i].print();
        while (cnt>=2&&((sta[cnt]-sta[cnt-1])*(p[i]-sta[cnt]))<0) cnt--;
        sta[++cnt]=p[i];
//      printf("Instack : \n");F(i,1,cnt) sta[i].print(); printf("\n\n");
    }
    D(i,top-1,1)
    if (fabs(p[i].x-p[i+1].x)>eps||fabs(p[i].y-p[i+1].y)>eps){
        while (cnt>=2&&((sta[cnt]-sta[cnt-1])*(p[i]-sta[cnt]))<0) cnt--;
        sta[++cnt]=p[i];
    }
    F(i,1,cnt-1) ans+=dist(sta[i],sta[i+1]);
    ans+=r*2*pi;
    printf("%.2f\n",ans);
//  F(i,1,cnt) sta[i].print();
}
 
int main()
{
    scanf("%d",&n);
    scanf("%lf%lf%lf",&a,&b,&r);
    a/=2;b/=2;a-=r;b-=r;
    F(i,0,3) v[i].x=mov[i][0]*b,v[i].y=mov[i][1]*a;
//  printf("Over\n");
    F(i,1,n)
    {
        scanf("%lf%lf%lf",&x,&y,&theta);
        Point now; now.x=x;now.y=y;
        F(j,0,3)
            p[++top]=now+Turn(v[j],theta);
    }
//  F(i,1,top) p[i].print();
    Andrew();
}

  

posted @ 2017-04-09 20:17  SfailSth  阅读(97)  评论(0编辑  收藏  举报