题目:
Alex is a circle of radius 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.
Alex’s is initially at position (0,y∞), where y∞ is much bigger than the width of the corridor 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), where x∞ is much bigger than ℓ). The lengths of the two doors are ℓ. It is guaranteed that ℓ≤w, so that door B will never hit the opposite side of the wall.
You are given T scenarios. In each scenario, the angles A and B are given (both are radians in the range [0,π]). Find the largest r≤R such that when Alex’s radius is shrunk to r, he can reach Bob while avoiding the obstacles (walls and doors).
Formally, Alex when shrunk to radius r can reach Bob if and only if there exists a (continuous) curve from (0,y∞) to (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. In particular, if r=0 then Alex will be able to reach Bob.
Input
The first line of input consists of three integers, R, ℓ, and w (1≤ℓ,w,R≤100and ℓ≤w). The second line of input consists of an integer T (1≤T≤10000), the number of scenarios to follow. Each of the next T lines consists of a pair of real numbers, representing angles A and B (in radians). The numbers are given with exactly 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 10−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范围内。讨论比较繁琐,要仔细细心。直接上代码。
代码:
#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);
}
}