2018 ACM-ICPC 沈阳站 Problem L. Machining Disc Rotors 几何

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/fanbaobao829/article/details/83305075
#include<bits/stdc++.h>
using namespace std;
const int maxn=205;
const double pi=acos(-1);
const double eps=1e-12;
typedef struct{double xi,yi,ri,thetas,thetat;} node1;
typedef struct{double thetas,thetat;} node2;
node2 a[maxn];
node1 p[maxn];
int cnta,cntp;
double get_distance(double xa,double ya,double xb,double yb)
{
    return sqrt((xa-xb)*(xa-xb)+(ya-yb)*(ya-yb));
}
bool cmp(node2 a,node2 b)
{
    return a.thetas<b.thetas;
}
double cal(node1 a1,node1 a2,double num)
{
    double l=a2.thetas,r=a2.thetat,ml,mr;
    if(r<l)
        r+=2*pi;
    while(r-l>eps)
    {
        ml=(2*l+r)/3;
        mr=(2*r+l)/3;
        if(get_distance(a1.xi+a1.ri*cos(num),a1.yi+a1.ri*sin(num),a2.xi+a2.ri*cos(ml),a2.yi+a2.ri*sin(ml))>get_distance(a1.xi+a1.ri*cos(num),a1.yi+a1.ri*sin(num),a2.xi+a2.ri*cos(mr),a2.yi+a2.ri*sin(mr)))
            r=mr;
        else
            l=ml;
    }
    return get_distance(a1.xi+a1.ri*cos(num),a1.yi+a1.ri*sin(num),a2.xi+a2.ri*cos(r),a2.yi+a2.ri*sin(r));
}
double cal(node1 a1,node1 a2)
{
    double l=a1.thetas,r=a1.thetat,ml,mr;
    if(r<l)
        r+=2*pi;
    while(r-l>eps)
    {
        ml=(2*l+r)/3;
        mr=(2*r+l)/3;
        if(cal(a1,a2,ml)>cal(a1,a2,mr))
            r=mr;
        else
            l=ml;
    }
    return cal(a1,a2,r);
}
int main()
{
    //freopen("test.out","r",stdin);
    int t,n,cas=1;
    double R,x,y,r;
    scanf("%d",&t);
    while(t--&&scanf("%d%lf",&n,&R)!=EOF)
    {
        cnta=cntp=0;
        for(int i=0;i<n;i++)
        {
            scanf("%lf%lf%lf",&x,&y,&r);
            double dis=get_distance(x,y,0,0);
            if(dis>=r+R)
                continue;
            if(r<R&&dis<R-r)
                continue;
            double tp_theta,theta1l,theta1r,theta2l,theta2r;
            tp_theta=acos(x/sqrt(x*x+y*y));
            if(y>0)
                tp_theta=2*pi-tp_theta;
            theta1l=acos((R*R-r*r-x*x-y*y)/2/r/sqrt(x*x+y*y));
            theta1r=2*pi-theta1l-tp_theta;
            theta1l-=tp_theta;
            if(theta1r<0)
                theta1r+=2*pi;
            if(theta1l<0)
                theta1l+=2*pi;
            if(theta1l>theta1r)
                swap(theta1l,theta1r);
            theta2l=acos((R*R-r*r+x*x+y*y)/2/R/sqrt(x*x+y*y));
            theta2r=2*pi-theta2l-tp_theta;
            theta2l-=tp_theta;
            if(theta2r<0)
                theta2r+=2*pi;
            if(theta2l<0)
                theta2l+=2*pi;
            if(theta2l>theta2r)
                swap(theta2l,theta2r);
            tp_theta=(theta1l+theta1r)/2;
            if(get_distance(x+r*cos(tp_theta),y+r*sin(tp_theta),0,0)<R)
                p[cntp++]=node1{x,y,r,theta1l,theta1r};
            else
                p[cntp++]=node1{x,y,r,theta1r,theta1l};
            tp_theta=(theta2l+theta2r)/2;
            if(get_distance(R*cos(tp_theta),R*sin(tp_theta),x,y)<r)
                a[cnta++]=node2{theta2l,theta2r};
            else
                a[cnta++]=node2{theta2r-2*pi,theta2l};
        }
        sort(a,a+cnta,cmp);
        for(int i=1;i<cnta;i++)
            p[cntp++]=node1{0,0,R,a[i-1].thetat,a[i].thetas};
        if(cnta)
            p[cntp++]=node1{0,0,R,a[cnta-1].thetat,a[0].thetas>=0?a[0].thetas:a[0].thetas+2*pi};
        else
            p[cntp++]=node1{0,0,R,0,pi*2};
        double ans=0;
        for(int i=0;i<cntp;i++)
            for(int j=0;j<=i;j++)
                ans=max(ans,cal(p[i],p[j]));
        printf("Case #%d: %.9f\n",cas++,ans);
    }
    return 0;
}
/*
1
3 10
0 12 10
11 -6 10
-11 -6 10
*/
#include<bits/stdc++.h>
using namespace std;
const int maxn=105;
const double pi=acos(-1);
const double eps=1e-12;
typedef struct{double thetas,thetat;} node;
node a[maxn],b[maxn];
int cnta,cntb;
double get_distance(double xa,double ya,double xb,double yb)
{
    return sqrt((xa-xb)*(xa-xb)+(ya-yb)*(ya-yb));
}
bool cmp(node a,node b)
{
    return a.thetas<b.thetas;
}
int main()
{
    int t,n,cas=1;
    double R,x,y,r,ans=0;
    scanf("%d",&t);
    while(t--&&scanf("%d%lf",&n,&R)!=EOF)
    {
        cnta=cntb=0;
        ans=0;
        for(int i=0;i<n;i++)
        {
            scanf("%lf%lf%lf",&x,&y,&r);
            double dis=get_distance(x,y,0,0);
            if(dis>=r+R)
                continue;
            if(r<R&&dis<R-r)
                continue;
            double tp_theta,thetal,thetar;
            tp_theta=acos(x/sqrt(x*x+y*y));
            if(y>0)
                tp_theta=2*pi-tp_theta;
            thetal=acos((R*R-r*r+x*x+y*y)/2/R/sqrt(x*x+y*y));
            thetar=2*pi-thetal-tp_theta;
            thetal-=tp_theta;
            if(thetar<0)
                thetar+=2*pi;
            if(thetal<0)
                thetal+=2*pi;
            if(thetal>thetar)
                swap(thetal,thetar);
            tp_theta=(thetal+thetar)/2;
            if(get_distance(R*cos(tp_theta),R*sin(tp_theta),x,y)<r)
                b[cntb++]=node{thetal,thetar};
            else
                b[cntb++]=node{thetar-2*pi,thetal};
        }
        sort(b,b+cntb,cmp);
        for(int i=1;i<cntb;i++)
            a[cnta++]=node{b[i-1].thetat,b[i].thetas};
        if(cntb)
        {
            a[cnta++]=node{b[cntb-1].thetat,b[0].thetas};
            for(int i=1;i<cnta;i++)
                for(int j=0;j<i;j++)
                {
                    double maxx=a[i].thetat-a[j].thetas,minn=a[i].thetas-a[j].thetat;
                    if(maxx<0)
                        maxx+=2*pi;
                    if(minn<0)
                        minn+=2*pi;
                    if(maxx<pi)
                        ans=max(ans,maxx);
                    else if(minn>pi)
                        ans=max(ans,2*pi-minn);
                    else
                        ans=pi;
                }
            ans=2*sin(ans/2)*R;
        }
        else
            ans=2*R;
        printf("Case #%d: %.9f\n",cas++,ans);
    }
    return 0;
}
/*
1
3 10
0 12 10
11 -6 10
-11 -6 10
*/

猜你喜欢

转载自blog.csdn.net/fanbaobao829/article/details/83305075