Kattis - doors Doors

本文探讨了一道算法题,要求计算一个圆形角色Alex在给定角度下能够穿过两个门到达目标位置的最大半径。文章提供了详细的解决方案及代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目:

Alex is a circle of radius  R R. 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  y y∞ is much bigger than the width of the corridor  w w. 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  x x∞ 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  T T scenarios. In each scenario, the angles  A A and  B B are given (both are radians in the range  [0,π] [0,π]). Find the largest  rR r≤R such that when Alex’s radius is shrunk to  r r, he can reach Bob while avoiding the obstacles (walls and doors).

Formally, Alex when shrunk to radius  r r 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  r r. In particular, if  r=0 r=0 then Alex will be able to reach Bob.

Input

The first line of input consists of three integers,  R R , and  w w ( 1,w,R100 1≤ℓ,w,R≤100and  w ℓ≤w). The second line of input consists of an integer  T T ( 1T10000 1≤T≤10000), the number of scenarios to follow. Each of the next  T T lines consists of a pair of real numbers, representing angles  A A and  B B (in radians). The numbers are given with exactly  4 4 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  105 10−5.

Sample Input 1Sample 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);
    }
}




此压缩包包含了本毕业设计项目的完整内容,具体包括源代码、毕业论文以及演示PPT模板。 开发语言:Java 框架:SSM(Spring、Spring MVC、MyBatis) JDK版本:JDK 1.8 或以上 开发工具:Eclipse 或 IntelliJ IDEA Maven版本:Maven 3.3 或以上 数据库:MySQL 5.7 或以上 项目配置完成后即可运行,若需添加额外功能,可根据需求自行扩展。 运行条件 确保已安装 JDK 1.8 或更高版本,并正确配置 Java 环境变量。 使用 Eclipse 或 IntelliJ IDEA 打开项目,导入 Maven 依赖,确保依赖包下载完成。 配置数据库环境,确保 MySQL 服务正常运行,并导入项目中提供的数据库脚本。 在 IDE 中启动项目,确认所有服务正常运行。 主要功能简述: 请假审批流程:系统支持请假申请的逐级审批,包括班主任审批和院系领导审批(针对超过三天的请假)。学生可以随时查看请假申请的审批进展情况。 请假记录管理:系统记录学生的所有请假记录,包括请假时间、原因、审批状态及审批意见等,供学生和审批人员查询。 学生在线请假:学生可以通过系统在线填写请假申请,包括请假的起止日期和请假原因,并提交给班主任审批。超过三天的请假需经班主任审批后,再由院系领导审批。 出勤信息记录:任课老师可以在线记录学生的上课出勤情况,包括迟到、早退、旷课和请假等状态。 出勤信息查询:学生、任课老师、班主任、院系领导和学校领导均可根据权限查看不同范围的学生上课出勤信息。学生可以查看自己所有学年的出勤信息,任课老师可以查看所教班级的出勤信息,班主任和院系领导可以查看本班或本院系的出勤信息,学校领导可以查看全校的出勤信息。 出勤统计与分析:系统提供出勤统计功能,可以按班级、学期等条件统计学生的出勤情况,帮助管理人员了解学生的出勤状况。 用户管理:系统管理员负责管理所有用户信息,包括学生、任课老师、班主任、院系领导和学校领导的账号创建、权限分配等。 数据维护:管理员可以动态更新和维护系统所需的数据,如学生信息、课程安排、学年安排等,确保系统的正常运行。 系统配置:管理员可以对系统进行配置,如设置数据库连接参数、调整系统参数等,以满足不同的使用需求。 身份验证:系统采用用户名和密码进行身份验证,确保只有授权用户才能访问系统。不同用户类型(学生、任课老师、班主任、院系领导、学校领导、系统管理员)具有不同的操作权限。 权限控制:系统根据用户类型分配不同的操作权限,确保用户只能访问和操作其权限范围内的功能和数据。 数据安全:系统采取多种措施保障数据安全,如数据库加密、访问控制等,防止数据泄露和非法访问。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值