题目:
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≤100 and ℓ≤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);
}
}