zoukankan      html  css  js  c++  java
  • Codeforces Round #357 (Div. 2) E. Runaway to a Shadow 计算几何

    E. Runaway to a Shadow

    题目连接:

    http://www.codeforces.com/contest/681/problem/E

    Description

    Dima is living in a dormitory, as well as some cockroaches.

    At the moment 0 Dima saw a cockroach running on a table and decided to kill it. Dima needs exactly T seconds for aiming, and after that he will precisely strike the cockroach and finish it.

    To survive the cockroach has to run into a shadow, cast by round plates standing on the table, in T seconds. Shadow casted by any of the plates has the shape of a circle. Shadow circles may intersect, nest or overlap arbitrarily.

    The cockroach uses the following strategy: first he equiprobably picks a direction to run towards and then runs towards it with the constant speed v. If at some moment t ≤ T it reaches any shadow circle, it immediately stops in the shadow and thus will stay alive. Otherwise the cockroach is killed by the Dima's precise strike. Consider that the Dima's precise strike is instant.

    Determine the probability of that the cockroach will stay alive.

    Input

    In the first line of the input the four integers x0, y0, v, T (|x0|, |y0| ≤ 109, 0 ≤ v, T ≤ 109) are given — the cockroach initial position on the table in the Cartesian system at the moment 0, the cockroach's constant speed and the time in seconds Dima needs for aiming respectively.

    In the next line the only number n (1 ≤ n ≤ 100 000) is given — the number of shadow circles casted by plates.

    In the next n lines shadow circle description is given: the ith of them consists of three integers xi, yi, ri (|xi|, |yi| ≤ 109, 0 ≤ r ≤ 109) — the ith shadow circle on-table position in the Cartesian system and its radius respectively.

    Consider that the table is big enough for the cockroach not to run to the table edges and avoid Dima's precise strike.

    Output

    Print the only real number p — the probability of that the cockroach will stay alive.

    Your answer will be considered correct if its absolute or relative error does not exceed 10 - 4.

    Sample Input

    0 0 1 1
    3
    1 1 1
    -1 -1 1
    -2 2 1

    Sample Output

    0.50000000000

    Hint

    题意

    有一个蟑螂,在x0,y0点,每秒移动,可以移动T秒,T秒后不在阴影中就会被拍死

    阴影都是圆,现在给你圆心坐标和圆的半径。

    这个蟑螂是随机选择一个方向走的

    问你这个蟑螂活下来的概率是多少

    题解:

    蟑螂和圆都会有一个角度的区间,表示在T秒内能够到达这个阴影中

    然后把所有区间拿出来,取并集

    然后再除以2pi就好了

    思路很简单。

    取区间的这个东西,用简单的初中几何知识就能得到。

    然后这道题就结束了。

    代码

    #include<bits/stdc++.h>
    using namespace std;
    const double eps = 1e-6;
    const double pi = acos(-1.0);
    double sqr(double x)
    {
        return x*x;
    }
    double dis(double x,double y,double x1,double y1)
    {
        return sqrt(sqr(x-x1)+sqr(y-y1));
    }
    vector<pair<double,int> >a;
    double x,y,v,t,r;
    int n;
    int main()
    {
    
        scanf("%lf%lf%lf%lf",&x,&y,&v,&t);
        r=v*t;
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            double x0,y0,r0;
            scanf("%lf%lf%lf",&x0,&y0,&r0);
            double D=dis(x,y,x0,y0);
            if(D<=r0)
            {
                cout<<"1.000000000"<<endl;
                return 0;
            }
            if(r+r0+eps<D)continue;
            double angl,angr,ang;
    
            double angm=atan2(y0-y,x0-x);
    
            if(angm<0)angm+=2*pi;
    
            double len1 = sqrt(D*D-r0*r0);
            if(len1<r+eps){
                ang=asin(r0/D);
            }
            else{
                ang=acos((D*D+r*r-r0*r0)/(2.0*D*r));
            }
    
            angl=angm-ang;
            angr=angm+ang;
    
            if(angl<0){
                a.push_back(make_pair(angl+2*pi,1));
                a.push_back(make_pair(2*pi,-1));
                a.push_back(make_pair(0,1));
                a.push_back(make_pair(angr,-1));
            }
            else if(angr>2*pi){
                a.push_back(make_pair(angl,1));
                a.push_back(make_pair(2*pi,-1));
                a.push_back(make_pair(0,1));
                a.push_back(make_pair(angr-2*pi,-1));
            }
            else{
                a.push_back(make_pair(angl,1));
                a.push_back(make_pair(angr,-1));
            }
        }
        sort(a.begin(),a.end());
        double ans = 0;
        double last = 0;
        int now = 0;
        for(int i=0;i<a.size();i++)
        {
            if(now>0)
                ans+=a[i].first-last;
            last=a[i].first;
            now+=a[i].second;
        }
        printf("%.12f
    ",ans/(2*pi));
    }
  • 相关阅读:
    png格式的img元素直接设置背景色、border-radius等属性,不需再包裹div造成冗余
    :before伪元素的灵活用法——前置元素的装饰
    linear-gradient在实战项目中的灵活运用——position和size的深入理解
    算法之单向链表
    awk(二)
    awk(一)
    grep与正则表达式
    编程原理
    Shell-bash的基本特性
    DNS域名轮循业务监控
  • 原文地址:https://www.cnblogs.com/qscqesze/p/5586322.html
Copyright © 2011-2022 走看看