Kattis - doors Doors

題目:

Alex is a circle of radius RR. Well, life as a circle is not easy. If he were a point, moving around and passing through doors would be effortless. But now he has to carefully inspect the surroundings before making every move.

\includegraphics[width=.6\textwidth ]{figure}

Alex’s is initially at position (0,y)(0,y∞), where yy∞ is much bigger than the width of the corridor ww. Alex wants to meet Bob, who happens to be living to the far right of the corridor (may as well be somewhere at (x,w/2)(x∞,w/2), where xx∞ is much bigger than ). The lengths of the two doors are . It is guaranteed that wℓ≤w, so that door B will never hit the opposite side of the wall.

You are given TT scenarios. In each scenario, the angles AA and BB are given (both are radians in the range [0,π][0,π]). Find the largest rRr≤R such that when Alex’s radius is shrunk to rr, he can reach Bob while avoiding the obstacles (walls and doors).

Formally, Alex when shrunk to radius rr can reach Bob if and only if there exists a (continuous) curve from (0,y)(0,y∞) to (x,w/2)(x∞,w/2) such that the minimal distance between a point on the curve and a point on an obstacle (a wall or a door) is at least rr. In particular, if r=0r=0 then Alex will be able to reach Bob.

Input

The first line of input consists of three integers, RR, and ww (1,w,R1001≤ℓ,w,R≤100and wℓ≤w). The second line of input consists of an integer TT (1T100001≤T≤10000), the number of scenarios to follow. Each of the next TT lines consists of a pair of real numbers, representing angles AA and BB (in radians). The numbers are given with exactly 44 decimal places.

Output

For each scenario, output the required answer on a separate line. Your answer will be accepted if its absolute or relative error (compared to the judge’s answer) is at most 10510−5.

Sample Input 1 Sample Output 1
10 6 8
4
0.0000 0.0000
3.1415 0.0000
1.0472 0.0000
1.0472 1.5708
0.000000000
3.000000000
2.598079885
1.000000000
題意:如圖,alex的半徑小於等於R,有兩扇門(綠線和藍線),輸入他的角度,alex 和bob都分別離門無限遠,問,是否alex可以穿過縫隙到達bob的位置

,求出能穿過的alex的最大半徑。

分析:分情況討論點與直線距離,保證能通過時,選取最大半徑。最後不要忘記再R範圍內。討論比較繁瑣,要仔細細心。直接上代碼。




代碼:

#include <cstdio>
#include <cmath>
#include <iostream>
#define PI 3.141592654
using namespace std;
struct line//直線ax+by+c=0, 記錄a,b,c的值
{
  double a, b, c;
};
line zhixian(double x1, double y1, double x2, double y2)//計算a ,b, c
{
    line q;
    if(x1 == x2) {
            q.a = 1;
            q.b = 0;
            q.c = -x1;
    }
    else if(y1 == y2){
           q.a = 0;
           q.b = 1;
           q.c = -y1;
    }
    else{
        q.a = y2-y1;
        q.b = x1-x2;
        q.c = (x2-x1)*y1 - (y2-y1)*x1;
    }
    return q;
}
double juli2(double x1, double y1, double x2, double y2)//兩點間距離
{
     return sqrt((y2-y1)*(y2-y1)+(x2-x1)*(x2-x1));
}
bool judge(double x1, double y1, double x2, double y2, double x3, double y3)//點到直線的距離中,與直線的交點可能不在線段(門)上,通過三點能否組成鈍角三角形判斷
{
    double a = juli2(x1, y1, x2, y2);
    double b = juli2(x1, y1, x3, y3);
    double c = juli2(x2, y2, x3, y3);
    if(c*c + a*a - b*b < 0) return true;
    return false;
}
double juli(double x, double y, line q)//計算點到直線距離
{
    return fabs(q.a*x + q.b*y + q.c) / sqrt(q.a*q.a + q.b*q.b);
}

int main()
{
    double R, l, w; cin >> R >> l >> w;
    int t; cin >> t;
    while(t--)
    {
        double p1, p2;
        cin >> p2 >> p1;
        double Mx, My, Nx, Ny;
            Mx = l - l*cos(p1);
            My = l*sin(p1);
            Nx = l - l*cos(p2);
            Ny = l*sin(p2)+w;
        double Ax = 0, Ay = w;
        double Bx = l, By = w;
        double Cx = l, Cy = 0;
        double ans = 0;

        if(p2 >= PI/2 && p1 < PI/2){
             if(judge(Bx,By,Mx,My,Cx,Cy))
             {
                 double d3 = juli2(Bx, By, Mx, My);
                 ans = min(d3, l);
             }
             else
             {
                double d = juli(Bx, By, zhixian(Cx, Cy, Mx, My));
                ans = min(d, l);
             }
        }

        else if(p2 >= PI/2 && p1 >= PI/2){
             double d = w - My;
             ans = min(d, l);
        }

        else if(p2 < PI/2 && p1 < PI/2){
             double d1, d2, d3;
             if(judge(Mx,My,Bx,By,Nx,Ny)) {
                double d4 = juli2(Mx, My, Bx, By);
                d1 = d4;
             }
             else {
                d1 = juli(Mx, My, zhixian(Bx, By, Nx, Ny));
             }

             if(judge(Cx,Cy,Mx,My,Bx,By)) {
                 double d6 = juli2(Bx, By, Mx, My);
                 d2 = d6;
             }
             else {
                d2 = juli(Bx, By, zhixian(Mx, My, Cx, Cy));
             }

             if(judge(Ax,Ay,Nx,Ny,Bx,By)) {
                double d9 = juli2(Ax, Ay, Nx, Ny);
                d3 = d9;
             }
             else {
                d3 = juli(Ax, Ay, zhixian(Bx, By, Nx, Ny));
             }
            ans = min(d1, d2);
            ans = min(ans, d3);
        }

        else if(p2 < PI/2 && p1 >= PI/2){
             double d2 = w - My;
             double d1;
             if(judge(Ax,Ay,Nx,Ny,Bx,By)) {
                  double d4 = juli2(Ax, Ay, Nx, Ny);
                  d1 = d4;
             }
             else {
                d1 = juli(Ax, Ay, zhixian(Bx, By, Nx, Ny));
             }
             ans = min(d1, d2);
        }
        ans /= 2;
        if(ans > R) ans = R;
        printf("%.9f\n", ans);
    }
}




發佈了41 篇原創文章 · 獲贊 12 · 訪問量 8587
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章