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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章