SHOI2012 credit card convex hull

Meaning of the questions:

Link Title
Title effect:
given n-th circular arc corners rectangle to pi / 4, and they find the circumference of the convex hull

Ideas:

At first glance it seems not ideas, but noted that when r = 0 is seeking a bare convex hull
consider when r is not equal to 0, the method is obtained before we press the convex hull perimeter
and then find the angle for each point of inflection, this arc length is then determined, can be accumulated. . .

for(int i=1;i<=m;++i)
{
    ans+=(q[i]-q[i+1]).dist();
    double cs=((q[i]-q[i+1])*(q[i+2]-q[i+1]))/(q[i]-q[i+1]).dist()/(q[i+1]-q[i+2]).dist();
        //点乘a*b=|a||b|cos<a,b>(a,b为向量)
    double dg=pi-acos(cs);
    ans+=dg*r;
}

After the final submission AC looked over the solution to a problem, found that the total accumulated length of the arc is a whole circumference of a circle, directly added to it.

for(int i=1;i<=m;++i)
    ans+=(q[i]-q[i+1]).dist();
ans+=2*pi*r;

Precautions:

pi refers to 180 degrees instead of 360 degrees (only I made this mistake it ...)

code:

#include<bits/stdc++.h>
using namespace std;
const int N=1e4+5;
const double eps=1e-7;
const double pi=3.1415926535898;
int n,m,cnt,per[N<<2];
double a,b,r;
struct point{double x,y;double dist(){return sqrt(x*x+y*y);}}p[N<<2],q[N<<2];
point operator+(point x,point y){return (point){x.x+y.x,x.y+y.y};}
point operator-(point x,point y){return (point){x.x-y.x,x.y-y.y};}
double operator*(point x,point y){return x.x*y.x+x.y*y.y;}
double operator^(point x,point y){return x.x*y.y-x.y*y.x;}
inline double readin(){double x;scanf("%lf",&x);return x;}
inline double lfabs(double x){return x<-eps?-x:x;}
inline point rot(point pp,double dg)
{
    return (point){pp.x*cos(dg)-pp.y*sin(dg),pp.y*cos(dg)+pp.x*sin(dg)};
}
struct cmpfunctor{
    inline bool operator()(int x,int y)
    {
        double dit=(p[x]-p[1])^(p[y]-p[1]);
        if(lfabs(dit)>eps) return dit>eps;
        return (p[x]-p[1]).dist()<(p[y]-p[1]).dist();
    }
};
inline void Graham()
{
    for(int i=2;i<=cnt;++i)
        if(p[i].x-p[1].x<-eps||(lfabs(p[i].x-p[1].x)<eps&&p[i].y-p[1].y<-eps))
            swap(p[1],p[i]);
    for(int i=1;i<=cnt;++i)per[i]=i;
    sort(per+2,per+cnt+1,cmpfunctor());
    q[++m]=p[1];
    for(int i=2;i<=cnt;++i)
    {
        int j=per[i];
        while(m>1&&((p[j]-q[m-1])^(q[m]-q[m-1]))>-eps) --m;
        q[++m]=p[j];
    }
    q[m+1]=q[1];q[m+2]=q[2];
}
inline double C()
{
    double ans=0;
    for(int i=1;i<=m;++i)
        ans+=(q[i]-q[i+1]).dist();
    return ans+2.0*pi*r;
}
int main()
{
    scanf("%d",&n);
    scanf("%lf%lf%lf",&a,&b,&r);
    for(int i=1;i<=n;++i)
    {
        point pt;scanf("%lf%lf",&pt.x,&pt.y);
        point ne=(point){pt.x+b/2.0-r,pt.y+a/2.0-r};
        point nw=(point){pt.x-b/2.0+r,pt.y+a/2.0-r};
        double dg=readin();
        p[++cnt]=rot(ne-pt,dg)+pt;p[++cnt]=rot(nw-pt,dg)+pt;
        point ps=pt+pt-p[cnt];p[++cnt]=ps;
        ps=pt+pt-p[cnt-2];p[++cnt]=ps;
    }
    Graham();
    printf("%.2lf",C());
    return 0;
}

Guess you like

Origin www.cnblogs.com/zmyzmy/p/12231716.html