题意:从Alex 到Bob的弧线,离墙和门最短的距离(在R范围内)。
S思路:分情况讨论,A , B 的角度分别与90°大小比较的情况组合。
+用了点到线段距离的模板
#include <iostream>
#include <algorithm>#include <cstdio>
#include <iomanip>
#include <string>
#include <cstring>
#include <cstdlib>
#include <vector>
#include <cmath>
# define pai 3.1415926
struct point
{
double x,y;
point(double xx=0,double yy=0):x(xx),y(yy){}
} ;
typedef point Vector ;
Vector operator +(Vector A,Vector B)
{return Vector (A.x+B.x,A.y+B.y);}
Vector operator -(point A,point B)
{return Vector (A.x-B.x,A.y-B.y);}
Vector operator *(Vector A,double p)
{
return Vector (A.x*p,A.y*p);
}
Vector operator /(Vector A,double p)
{return Vector (A.x/p,A.y/p);}
bool operator < (const point &a,const point &b)
{
return a.x<b.x||(a.x==b.x&&a.y<b.y);
}
const double eps=1e-10;
int dcmp(double x)
{
if(fabs(x)<eps)return 0;
else return x<0?-1:1;
}
bool operator==(const point &a,const point &b)
{
return dcmp(a.x-b.x)==0 &&dcmp(a.y-b.y)==0;
}double Dot(Vector A,Vector B)
{
return (A.x*B.x+A.y*B.y);
}
double length( Vector A)
{
return sqrt(Dot( A,A));
}
double angle(Vector A,Vector B)
{
return acos(Dot(A,B)/length(A)/length(B));
}
double Cross(Vector A,Vector B)
{
return A.x*B.y-A.y*B.x;
}
double dis( point P, point A,point B)
{
if(A==B) return length(P-A);
Vector v1= B-A, v2=P-A, v3=P-B;
if(dcmp(Dot(v1,v2)<0) )return length(v2);
else if(dcmp(Dot(v1,v3))>0)return length(v3);
else return fabs(Cross(v1,v2)/length(v1));
}
/以上套用点到线段距离模板
using namespace std;
int main()
{
int R,l,w,n;
double a,b;
scanf("%d %d %d",&R,&l,&w);
scanf("%d",&n);
for(int i=0;i<n;i++)
{
scanf("%lf %lf",&a,&b);
double r1= dis(point(0,w),point(l-l*cos(a),w+l*sin(a)),point(l,w))/2.0;
double r2=dis(point(l,w),point(l-l*cos(b),l*sin(b)),point(l,0))/2.0;
double r3=dis(point(l-l*cos(b),l*sin(b)),point(l,w),point(l-l*cos(a),w+l*sin(a)))/2.0;
double rr=R;
//讨论4种情况
if(a<pai/2.0&&b<pai/2.0)//{
rr=min(r1,r2);
rr=min(rr,r3);
}
else if(a>=pai/2.0&&b<=pai/2.0)
{
rr=l/2.0;
// //rr=min(rr,r3)此处注意是r2
rr=min(rr,r2);
}
else if(a>=pai/2&&b>=pai/2)
{
rr=l/2.0;
rr=min(rr,(double)(w-l*sin(pai-b))/2.0);
}
else if(a<=pai/2&&b>=pai/2)
{
rr=r1;
rr=min(rr,(double)(w-l*sin(pai-b))/2.0);
}
//最后别忘记与l与R的大小讨论
if(rr>(double)w/2.0)rr=(double)w/2.0;
if(rr>(double)l/2.0)
rr=l/2.0;
if(rr>R)
rr=R;
printf("%.9f\n",rr);
}
}