bzoj2829: 信用卡凸包 计算几何 凸包

来源:互联网 发布:java 并发编程的书 编辑:程序博客网 时间:2024/05/17 01:05

因为凸包是凸多边形 内角和=(n-2)*180 而所有由圆弧构成的圆心角=n*180-(n-2)*180=360 即一个圆周。然后直接算凸包就可以了。

#include <iostream>#include <algorithm>#include <cstdio>#include <cstring>#include <cmath>using namespace std;#define pi acos(-1.0)#define maxn 410000#define eps 1e-8int n,cnt;struct node{    double x,y;}p[maxn],dir[10];struct rec{    node a;    double ang;}o[maxn];double a,b,r,ans;double sqr(double x){    return x*x;}double dis(node a,node b){    return (sqr(a.x-b.x)+sqr(a.y-b.y));}double operator * (node a,node b){    return a.x*b.y-a.y*b.x;}node operator - (node a,node b){    node t;    t.x=a.x-b.x; t.y=a.y-b.y;    return t;}node operator + (node a,node b){    node t;    t.x=a.x+b.x; t.y=a.y+b.y;    return t;}bool cmp(node a,node b){    if(fabs((a-p[1])*(b-p[1]))<eps)return dis(p[1],a)<dis(p[1],b);    return (a-p[1])*(b-p[1])>0;}bool operator<(node a,node b){    if(fabs(a.y-b.y)<eps)return a.x<b.x;    return a.y<b.y;}node change(node tmp,double ang){    node get;    get.x=tmp.x*cos(ang)-tmp.y*sin(ang);    get.y=tmp.y*cos(ang)+sin(ang)*tmp.x;    return get;}void getp(){    node tmp;    for(int i=1;i<=n;i++)    {        for(int j=1;j<=4;j++)        {            tmp=change(dir[j],o[i].ang);            cnt++;p[cnt]=o[i].a+tmp;            //printf("%.2lf %.2lf ",p[cnt].x,p[cnt].y);        }        //printf("\n");    }}void init(){    dir[1].x=-b/2;dir[1].y=a/2;    dir[2].x=-b/2;dir[2].y=-a/2;    dir[3].x=b/2;dir[3].y=a/2;    dir[4].x=b/2;dir[4].y=-a/2;}int s[maxn],top;void solve(){    for(int i=1;i<=cnt;i++) if(p[i]<p[1])swap(p[i],p[1]);    sort(p+2,p+cnt+1,cmp);    s[1]=1;s[2]=2;top=2;    for(int i=3;i<=cnt;i++)    {        for(;top>1 && (p[s[top]]-p[s[top-1]])*(p[i]-p[s[top-1]])<-eps;top--);        top++;s[top]=i;    }    s[top+1]=1;    for(int i=1;i<=top;i++) ans+=sqrt(dis(p[s[i]],p[s[i+1]]));}int main(){    scanf("%d",&n);    scanf("%lf%lf%lf",&a,&b,&r);    a-=2*r;b-=2*r;    init();    ans+=2*pi*r;    for(int i=1;i<=n;i++)    {        scanf("%lf%lf%lf",&o[i].a.x,&o[i].a.y,&o[i].ang);    }    getp();    solve();    printf("%.2lf",ans);    return 0;}


0 0