zoukankan      html  css  js  c++  java
  • 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
    ",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
    ",maxi);
        }
        return 0;
    }
    View Code
  • 相关阅读:
    百度音乐搜索API
    浅谈对设计模式的理解
    AS3 Embed
    AS3.0中遍历删除容器内子对象的误区。
    如何获取GridView的总记录数?
    分享几个国外的Ajax&Jquery网站
    SQL2000: MMC 不能打开文件
    结合.net开发 谈谈 access 中 模糊查询语句 like的用法
    [转]C#里巧用DateTime预设一些可选的日期范围(如本年度、本季度、本月等)
    根据条件动态改变GridView某行或某个单元格的背景色
  • 原文地址:https://www.cnblogs.com/whatbeg/p/3905541.html
Copyright © 2011-2022 走看看