4667 Building Fence solution report

Source: Internet
Author: User
Tags acos

Give n circles and m triangles, and make sure they do not intersect each other. Use a fence to enclose them and find the shortest perimeter.

Solution 1: Take 2000 points evenly on each circle, and find the circumference of the convex hull to allow water to pass through.

Solution 2: Find the tangent points of the outer public tangent between all circles, as well as the straight lines and the circle tangent points of each vertex of the triangle, and the three vertices of the triangle. These points are convex packets to determine the graph on the edge of the fence. The sum of the sides and arcs of the convex hull is required. Determine whether the arc is an excellent arc or an inferior arc when determining the arc length. Use the cross product to determine the direction of the two vectors.

 

//Time:218MS//Memory:860Kinclude <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <iostream>using namespace std;const double EPS = 1e-10;const double PI = acos(-1.0);const int MAXN = 55;int dcmp(double x){    if(fabs(x)<EPS) return 0;    return x<0? -1:1;}double sqr(double x){    return x*x;}struct Point{    double x,y;    bool tp;    int id;    Point(){}    Point(double a,double b):x(a),y(b){}    Point operator +(const Point &a)const{return Point(x+a.x,y+a.y);}    Point operator -(const Point &a)const{return Point(x-a.x,y-a.y);}    Point operator *(double k) const{return Point(x*k,y*k);}    Point operator /(double k) const{return Point(x/k,y/k);}    bool operator <(const Point &a)const    {        return dcmp(x-a.x)<0||(dcmp(x-a.x)==0&&dcmp(y-a.y)<0);    }    bool operator ==(const Point &a)const    {        return dcmp(x-a.x)==0&&dcmp(y-a.y)==0;    }    Point trunc(double d)    {        double dist(Point ,Point);        double len = dist(*this,Point(0,0));        return Point(x*d/len,y*d/len);    }    Point rotate(double a)    {        return Point(x*cos(a)-y*sin(a),y*cos(a)+x*sin(a));    }    void input(){scanf("%lf%lf",&x,&y);}};struct Circle{    Point o;    double r;    Circle(){}    Circle(Point a,double b):o(a),r(b){}    double area(){return sqr(r)*PI;}    double len(double ang){return r*ang;}};struct Tri{    Point p[3];};typedef Point Vector;double cross(Vector a,Vector b){    return a.x*b.y-a.y*b.x;}double dot(Vector a,Vector b){    return a.x*b.x+a.y*b.y;}double length(Vector a){    return sqrt(dot(a,a));}double dist(Point a,Point b){    return length(a-b);}double v_angle(Vector a,Vector b){    return acos(dot(a,b)/length(a)/length(b));}int ConvexHull(Point *p, int n, Point *ch){    sort(p, p+n);    n = unique(p, p+n) - p;    int m = 0;    for(int i = 0; i < n; i++)    {        while(m > 1 && dcmp(cross(ch[m-1]-ch[m-2], p[i]-ch[m-2])) <= 0) m--;        ch[m++] = p[i];    }    int k = m;    for(int i = n-2; i >= 0; i--)    {        while(m > k && dcmp(cross(ch[m-1]-ch[m-2], p[i]-ch[m-2])) <= 0) m--;        ch[m++] = p[i];    }    if(n > 1) m--;    return m;}Vector rotate(Vector a,double rad){    Vector c;    c.x = a.x*cos(rad)-a.y*sin(rad);    c.y = a.x*sin(rad)+a.y*cos(rad);    return c;}void get_ocmt(Circle c1,Circle c2,Point &s1, Point &e1,Point &s2,Point &e2){    double l = dist(c1.o,c2.o);    double d = fabs(c1.r-c2.r);    double theta = acos(d/l);    //if(dcmp(c1.r-c2.r)>0) swap(c1,c2);    Vector vec = c1.o-c2.o;    vec = vec.trunc(c1.r);    s1 = c1.o+rotate(vec,theta);    s2 = c1.o+vec.rotate(-theta);    vec = vec.trunc(c2.r);    e1 = c2.o+vec.rotate(theta);    e2 = c2.o+vec.rotate(-theta);}void get_pc(Circle c, Point p,Point &s1,Point &s2){    Vector u = p-c.o;    double dist = length(u);    Point v = c.o+u/dist*c.r;    double ang = PI/2-asin(c.r/dist);    s1 = rotate(v-c.o,-ang)+c.o;    s2 = rotate(v-c.o,ang)+c.o;}Point p[55*55*55],ch[55*55*55];int main(){    //freopen("/home/qitaishui/code/in.txt","r",stdin);    int n,m,pn,chn;    Circle c[MAXN];    Tri tri[MAXN];    while(scanf("%d%d",&n,&m)!=EOF)    {        for(int i = 0; i < n;i++)        {            c[i].o.input();            scanf("%lf",&c[i].r);        }        if(n==1&&m==0)        {            printf("%.6f\n",c[0].len(2*PI));            continue;        }        for(int i = 0; i < m; i++)            for(int j = 0; j < 3; j++)                tri[i].p[j].input();        pn = 0;        for(int i = 0; i < n; i++)            for(int j = i+1; j < n; j++)            {                if(dcmp(c[i].r-c[j].r)>0)                    get_ocmt(c[j],c[i],p[pn+1],p[pn],p[pn+3],p[pn+2]);                else                    get_ocmt(c[i],c[j],p[pn],p[pn+1],p[pn+2],p[pn+3]);                p[pn].tp = 0,p[pn].id = i;                p[pn+1].tp = 0,p[pn+1].id = j;                p[pn+2].tp = 0,p[pn+2].id = i;                p[pn+3].tp = 0,p[pn+3].id = j;                pn+=4;            }        for(int i = 0; i < n; i++)            for(int j = 0; j < m; j++)                for(int k = 0; k <3; k++)                {                    get_pc(c[i],tri[j].p[k],p[pn],p[pn+1]);                    p[pn].tp = 0,p[pn].id = i;                    p[pn+1].tp = 0,p[pn+1].id = i;                    pn+=2;                }        for(int j = 0; j < m; j++)            for(int k = 0; k <3; k++)            {                p[pn] = tri[j].p[k];                p[pn].tp = 1, p[pn].id = j;                pn++;            }        chn = ConvexHull(p,pn,ch);        //cout<<chn<<endl;        int top=0;        bool flag = 0;        double ans = 0,cir=0;        for(int i = 0; i <chn; i++)        {            if(ch[i].tp==0&&ch[(i+1)%chn].tp==0&&ch[i].id==ch[(i+1)%chn].id)            {                int tmp=ch[i].id;                double ang;                ang = v_angle(ch[i]-c[tmp].o,ch[(i+1)%chn]-c[tmp].o);                if(dcmp(cross(ch[i]-c[tmp].o,ch[(i+1)%chn]-c[tmp].o))<0)                    ang = 2*PI-ang;                ans=ans+c[tmp].len(ang);            }            else                ans+=length(ch[i]-ch[(i+1)%chn]);        }        printf("%.6f\n",ans);    }    return 0;}

 

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.