UVALive 6092 Catching Shade in Flatland --枚举+几何计算

题意:x=[-200,200],y=[-200,200]的平面,一天中太阳从不同角度射到长椅(原点(0,0))上,有一些树(用圆表示),问哪个时刻(分钟为单位)太阳光线与这些圆所交的弦长总和最长。太阳距离原点总是500m。(这些圆不会互相相交,每个圆都不包括原点或者不经过原点

解法:直接暴力24*60分钟,找出此时的角度,然后求出直线方程,再枚举每个圆,求出弦长。注意这里每个圆都不包括原点,所以直线与圆的交点一定在同一侧,所以。。我当时想多了,没看清题目。把他当成可以包含原点了,代码超长,幸好过了。

代码:

没想多应该这样就可以了:

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cmath>

#include <algorithm>

#include <cstdlib>

#define INint 2147483647

#define pi acos(-1.0)

#define eps 1e-4

using namespace std;

#define N 100102

#define M 22



typedef struct point

{

    double x,y;

    point(double x=0,double y=0):x(x),y(y){}

}Vector;



double DegtoRad(double deg)

{

    return deg/180.0*pi;

}



int dcmp(double x)

{

    if(fabs(x)<eps) return 0;

    return x<0?-1:1;

}

Vector operator  + (Vector A,Vector B){return Vector(A.x+B.x,A.y+B.y);}

Vector operator  -  (point A,point B){return Vector(A.x-B.x,A.y-B.y);  }

Vector operator  *  (Vector A,double p){return Vector(A.x*p,A.y*p);}

Vector operator  /  (Vector A,double p){return Vector(A.x/p,A.y/p);}

bool operator ==  (const point& a,const point& b){return dcmp(a.x-b.x)==0&&dcmp(a.y-b.y)==0;}

bool operator < (const point& a,const point& b){return a.x<b.x ||(a.x==b.x&&a.y<b.y);}

double Cross(Vector A,Vector B){return A.x*B.y-A.y*B.x;}   //叉积 ,大于零说明B在A的左边。小于零说明B在A的右边

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 DistanceToSegment(point P,point A,point B)

{

    if(A==B) return length(P-A);

    Vector v1=B-A,v2=P-A,v3=P-B;

    if(dcmp(Dot(v1,v2))<0)  return length(v2);

    else if(dcmp(Dot(v1,v3))>0) return length(v3);

    else return fabs(Cross(v1,v2))/length(v1);

}



point p[205];

double ra[205];



int main()

{

    int n,i,j;

    while(scanf("%d",&n)!=EOF && n)

    {

        for(i=0;i<n;i++)

            scanf("%lf%lf%lf",&p[i].x,&p[i].y,&ra[i]);

        double maxi = 0.0;

        int S = 24*60;

        for(i=0;i<S;i++)

        {

            point A,B,C;

            A = point(0.0,0.0);

            double rad = DegtoRad(i/4.0);

            B = point(500*sin(rad),500*cos(rad));

            double sum = 0.0;

            for(j=0;j<n;j++)

            {

                C = p[j];

                double dis = DistanceToSegment(C,A,B);

                if(dis >= ra[j])

                    continue;

                sum += 2.0*sqrt(ra[j]*ra[j]-dis*dis);

            }

            maxi = max(maxi,sum);

        }

        printf("%.3lf\n",maxi);

    }

    return 0;

}
View Code

 

当时的代码(考虑了可能包含原点):

#include <iostream>

#include <cstdio>

#include <cstring>

#include <cmath>

#include <algorithm>

#include <cstdlib>

#define pi acos(-1.0)

using namespace std;

#define N 100102

#define M 22



struct node

{

    double x,y,r;

}p[205];



int getPlane(double nx,double ny)

{

    if(nx > 0 && ny > 0)

        return 1;

    else if(nx > 0 && ny < 0)

        return 2;

    else if(nx < 0 && ny < 0)

        return 3;

    else if(nx < 0 && ny > 0)

        return 4;

    else

        return 1;

}



double dis(int nx,int ny)

{

    return sqrt(nx*nx + ny*ny);

}



int main()

{

    int n,i,j;

    while(scanf("%d",&n)!=EOF && n)

    {

        for(i=0;i<n;i++)

            scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].r);

        int S = 24*60;

        double Si = 24.0*60.0;

        int Plane;

        double maxi = 0.0;

        for(i=0;i<S;i++)

        {

            if(i == 0 || i == 360 || i == 720 || i == 1080)

                continue;

            double A = tan(2*pi*(double)i/Si);

            double B = -1.0;

            double k = A;

            double di = sqrt(A*A+B*B);

            if(i > 0 && i < 360)

                Plane = 1;

            else if(i > 360 && i < 720)

                Plane = 2;

            else if(i > 720 && i < 1080)

                Plane = 3;

            else

                Plane = 4;

            double sum = 0.0;

            for(j=0;j<n;j++)

            {

                double x = p[j].x;

                double y = p[j].y;

                double r = p[j].r;

                double PtoL = fabs(A*x-y)/di;

                if(PtoL > r)

                    continue;

                double AA = k*k+1.0;

                double BB = -(2.0*x+2.0*k*y);

                double CC = x*x + y*y - r*r;

                if(BB*BB-4.0*AA*CC <= 0.0)

                    continue;

                double jie1x = (-BB+sqrt(BB*BB-4.0*AA*CC))/(2.0*AA);

                double jie1y = k*jie1x;

                double jie2x = (-BB-sqrt(BB*BB-4.0*AA*CC))/(2.0*AA);

                double jie2y = k*jie2x;

                int P1 = getPlane(jie1x,jie1y);

                int P2 = getPlane(jie2x,jie2y);

                if(P1 == Plane && P2 == Plane)

                    sum += 2.0*sqrt(r*r-PtoL*PtoL);

                else if(P1 == Plane)

                    sum += dis(jie1x,jie1y);

                else if(P2 == Plane)

                    sum += dis(jie2x,jie2y);

            }

            maxi = max(maxi,sum);

        }

        //up

        double sum = 0.0;

        for(j=0;j<n;j++)

        {

            double x = p[j].x;

            double y = p[j].y;

            double r = p[j].r;

            double PtoL = x;

            if(PtoL > r)

                continue;

            double AA = 1.0;

            double BB = -2.0*y;

            double CC = x*x + y*y - r*r;

            double jie1x = 0.0;

            double jie1y = (-BB+sqrt(BB*BB-4.0*AA*CC))/(2.0*AA);

            double jie2x = 0.0;

            double jie2y = (-BB-sqrt(BB*BB-4.0*AA*CC))/(2.0*AA);

            if(jie1y > 0 && jie2y > 0)

                sum += fabs(jie1y-jie2y);

            else if(jie1y > 0)

                sum += jie1y;

            else if(jie2y > 0)

                sum += jie2y;

        }

        maxi = max(maxi,sum);

        //down

        sum = 0.0;

        for(j=0;j<n;j++)

        {

            double x = p[j].x;

            double y = p[j].y;

            double r = p[j].r;

            double PtoL = x;

            if(PtoL > r)

                continue;

            double AA = 1.0;

            double BB = -2.0*y;

            double CC = x*x + y*y - r*r;

            double jie1x = 0.0;

            double jie1y = (-BB+sqrt(BB*BB-4.0*AA*CC))/(2.0*AA);

            double jie2x = 0.0;

            double jie2y = (-BB-sqrt(BB*BB-4.0*AA*CC))/(2.0*AA);

            if(jie1y < 0 && jie2y < 0)

                sum += fabs(jie1y-jie2y);

            else if(jie1y < 0)

                sum += -jie1y;

            else if(jie2y < 0)

                sum += -jie2y;

        }

        maxi = max(maxi,sum);

        //right

        sum = 0.0;

        for(j=0;j<n;j++)

        {

            double x = p[j].x;

            double y = p[j].y;

            double r = p[j].r;

            double PtoL = y;

            if(PtoL > r)

                continue;

            double AA = 1.0;

            double BB = -2.0*x;

            double CC = x*x + y*y - r*r;

            double jie1x = (-BB+sqrt(BB*BB-4.0*AA*CC))/(2.0*AA);

            double jie1y = 0.0;

            double jie2x = (-BB-sqrt(BB*BB-4.0*AA*CC))/(2.0*AA);

            double jie2y = 0.0;

            if(jie1x > 0 && jie2x > 0)

                sum += fabs(jie1x-jie2x);

            else if(jie1x > 0)

                sum += jie1x;

            else if(jie2x > 0)

                sum += jie2x;

        }

        maxi = max(maxi,sum);

        //left

        sum = 0.0;

        for(j=0;j<n;j++)

        {

            double x = p[j].x;

            double y = p[j].y;

            double r = p[j].r;

            double PtoL = y;

            if(PtoL > r)

                continue;

            double AA = 1.0;

            double BB = -2.0*x;

            double CC = x*x + y*y - r*r;

            double jie1x = (-BB+sqrt(BB*BB-4.0*AA*CC))/(2.0*AA);

            double jie1y = 0.0;

            double jie2x = (-BB-sqrt(BB*BB-4.0*AA*CC))/(2.0*AA);

            double jie2y = 0.0;

            if(jie1x < 0 && jie2x < 0)

                sum += fabs(jie1x-jie2x);

            else if(jie1x < 0)

                sum += -jie1x;

            else if(jie2x < 0)

                sum += -jie2x;

        }

        maxi = max(maxi,sum);

        printf("%.3lf\n",maxi);

    }

    return 0;

}
View Code

 

你可能感兴趣的:(catch)