zoukankan      html  css  js  c++  java
  • 吉林大学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;
    }
  • 相关阅读:
    android使用广播退出应用程序
    Calling startActivity() from outside of an Activity context requires the FLAG_ACTIVITY_NEW _TASK flag.
    Android获取屏幕尺寸大小
    onActivityResult不被执行的问题。
    ADB操作多台设备
    在Eclipse的DDMS中查看手机data文件夹中的内容
    JDK版本过高,导致Eclipse报错
    Android colors.xml
    Eclipse智能提示
    在配置IIS负载均衡时,引起的一系列问题
  • 原文地址:https://www.cnblogs.com/yejianfei/p/2646649.html
Copyright © 2011-2022 走看看