• 吉林大学OJ第2775题 Problem F: Shadows


      吉林大学OJ第2775题,Problem F: Shadows题目链接)。

    Problem F: Shadows

    “No sunshine but bath some shadow”. A shadow is an area where direct light from a light source cannot reach due to obstruction by an object. It occupies all of the space behind an opaque object with light in front of it.

    Let us consider a simplified 2-D problems. There is a lamp at the origin and an unlimited wall on the straight line x=d. Some opaque objects float between them. All these objects are circle. The wall will be separated into light and shadow. The shadow of each circle may be overlapping no matter the circles are intersected or not.

    Your task is to count the length of all shadows.

    Input

    The first line of each case are d and n. The real number d is the distance between wall and lamp, and integer n(0 < n < 100) is the number of circles. n=0 means the end of input.

    The next n lines consist of three real number x, y and r. x and y are the coordinates of circle center. r is the radius of circle opaque object. The entire area of each circle is between the two straight lines x=0 and x=d.

    Output

    For each case, print the total length of all shadows, rounded to two digits after decimal point.

    Sample Input

    10.0 2
    5 0 2
    3 1 2
    10 0

    Sample Output

    20.16

      解题思路:用三角函数,算出各个圆的经过原点的切线的斜率。从而算出影子的上下界。然后按照上界排序。外离和外切,影子总长加上影子长度,更新当前下界;相交的,影子总长加上影子下界减去最新下界,更新当前下界,内切和内含的,忽略不计。最终输出影子总长。

      C++语言源代码如下:

    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    
    using namespace std;
    
    typedef int COUNT;
    typedef struct { double top, bottom; } Circle;
    
    bool cmp(const Circle & a, const Circle & b )
    {
        if ( a.top > b.top )
            return true;
        else
            return false ;
    }
    
    int main (void)
    {
        COUNT i, n;
        double distance;
        double x, y, r;
        double sum;
        double angle, angle_diff, top_angle, bottom_angle;
        Circle circle[105];
        double bottom;
    
        while ( scanf( "%lf%d", &distance, &n ) , n ) 
        {
            for ( i = 0 ; i < n ; i ++ )
            {
                scanf( "%lf%lf%lf", &x, &y, &r );
                angle = atan( y / x );
                angle_diff = asin( r / sqrt(x*x + y*y) );
                top_angle = angle + angle_diff;
                bottom_angle = angle - angle_diff;
                circle[i].top = distance * tan(top_angle);
                circle[i].bottom = distance * tan(bottom_angle );
            }
            sort(circle, circle + n, cmp );
    
            bottom = circle[0].bottom;
            sum = circle[0].top - circle[0].bottom;
            for ( i = 1 ; i < n ; i ++ )
            {
                if ( circle[i].top <= bottom )
                {
                    sum += circle[i].top - circle[i].bottom ;
                    bottom = circle[i].bottom;
                }
                else
                {
                    if (circle[i].bottom < bottom )
                    {
                        sum += bottom - circle[i].bottom ;
                        bottom = circle[i].bottom ;
                    }
                }
            }
            printf( "%.2lf\n", sum );
        }
        return EXIT_SUCCESS;
    }
  • 相关阅读:
    phpstudy下允许所有的目录科访问
    fastadmin怎么自动生成框架目录
    优化数据库
    git操作是出现Username for 'https://github.com':的验证问题
    git上传命令步骤
    mysql 组合两张表
    删除重复的电子邮箱
    Neo4j
    opencv学习笔记(2
    opencv学习笔记(1)
  • 原文地址:https://www.cnblogs.com/yejianfei/p/2646649.html
Copyright © 2020-2023  润新知