題目:
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);
}
}