读懂题意发现是傻逼状压。
只要会向量旋转,以及直线求交点坐标就行了。(验证了我这俩板子都没毛病)
细节蛮多。
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
using namespace std;
const double PI=acos(-1.0);
#define EPS 0.00000001
struct Point
{
double x,y;
Point(){}
Point(const double &X,const double &Y)
{
x=X;
y=Y;
}
}p[23];
typedef Point Vector;
Vector operator - (const Point &a,const Point &b)
{
return Vector(a.x-b.x,a.y-b.y);
}
Vector operator + (const Vector &a,const Vector &b)
{
return Vector(a.x+b.x,a.y+b.y);
}
double Cross(Vector a,Vector b)
{
return a.x*b.y-a.y*b.x;
}
Vector operator * (const double &K,const Vector &v)
{
return Vector(K*v.x,K*v.y);
}
double ang[23],f[1<<22];
int n,L,R;
Vector Rotate(Vector A,double rad)
{
return Vector(A.x*cos(rad)-A.y*sin(rad),
A.x*sin(rad)+A.y*cos(rad));
}
Point GetIntersection(Point P,Vector v,Point Q,Vector w)
{
return P+(Cross(w,P-Q)/Cross(v,w))*v;
}
double calc(Point p,double rad,double x)
{
Vector v1=Rotate(Point(x,0)-p,rad);
if(v1.y>(-EPS))
return 2147483647.0;
return GetIntersection(p,v1,Point(0.0,0.0),Vector(1.0,0.0)).x;
}
int main()
{
//freopen("d.in","r",stdin);
scanf("%d%d%d",&n,&L,&R);
for(int i=1;i<=n;++i)
{
scanf("%lf%lf%lf",&p[i].x,&p[i].y,&ang[i]);
ang[i]=ang[i]/180.0*PI;
}
for(int i=0;i<(1<<n);++i)
f[i]=-2147483647.0;
f[0]=L;
for(int i=0;i<(1<<n);++i)
for(int j=1;j<=n;++j)
if(!((i>>(j-1))&1))
{
f[i|(1<<(j-1))]=max(f[i|(1<<(j-1))],calc(p[j],ang[j],f[i]));
if(f[i|(1<<(j-1))]-(double)R>(-EPS))
{
printf("%.9lf\n",(double)(R-L));
return 0;
}
}
printf("%.9lf\n",f[(1<<n)-1]-(double)L);
return 0;
}