mt19937 nsc(time(0));
const int N=105;
const double eps=1e-8,inf=1e18,pi=acos(-1);
int n;
double S,SS;
inline int cmp(double a,double b){
if(fabs(a-b)<eps)return 0;
return a>b?1:-1;
}
struct point{
double x,y;
point() {}
point (double xx,double yy){x=xx,y=yy;}
point operator +(const point &a)const{return point(x+a.x,y+a.y);}
point operator -(const point &a)const{return point(x-a.x,y-a.y);}
point operator *(const double &a)const{return point(x*a,y*a);}
point operator /(const double &a)const{return point(x/a,y/a);}
double operator *(const point &a)const{return x*a.y-y*a.x;}
double operator /(const point &a)const{return x*a.x+y*a.y;}
double length(){return sqrt(x*x+y*y);}
};
struct segment{
point a,b;
segment() {}
segment(point aa,point bb){a=aa,b=bb;}
inline double length(){return (b-a).length();}
bool operator <(const segment &x)const{return 0;}
}a[N],line;
double f[N][N][2];
inline bool checkcap(double l1,double r1,double l2,double r2){
if(r1<l1)swap(l1,r1);
if(r2<l2)swap(l2,r2);
if(!~cmp(r1,l2))return 0;
if(!~cmp(r2,l1))return 0;
return 1;
}
inline bool cross(segment a,segment b){
if(!checkcap(a.a.x,a.b.x,b.a.x,b.b.x))return 0;
if(!checkcap(a.a.y,a.b.y,b.a.y,b.b.y))return 0;
int flag1=cmp((a.b-a.a)*(b.a-a.a),0),flag2=cmp((a.b-a.a)*(b.b-a.a),0);
if(abs(flag1-flag2)!=2)return 0;
flag1=cmp((b.b-b.a)*(a.a-b.a),0),flag2=cmp((b.b-b.a)*(a.b-b.a),0);
if(abs(flag1-flag2)!=2)return 0;
return 1;
}
inline pair<double,segment> geth(point a,segment x){
point p=x.b-x.a;
double len=((a-x.a)/(x.b-x.a))/p.length();
if(cmp(len,p.length())>0)return make_pair(inf,x);
if(cmp(len,0)<0)return make_pair(inf,x);
point h=x.a+p*(len/p.length());
segment ans=segment(a,h);
return make_pair(ans.length(),ans);
}
inline void solve(segment a,segment b,int i,int j){
pair<double,segment> ans=min(make_pair(segment(a.a,b.a).length(),segment(a.a,b.a)),make_pair(segment(a.a,b.b).length(),segment(a.a,b.b)));
ans=min({ans,make_pair(segment(a.b,b.a).length(),segment(a.b,b.a)),make_pair(segment(a.b,b.b).length(),segment(a.b,b.b))});
ans=min({ans,geth(a.a,b),geth(a.b,b)});
pair<double,segment> minn=min(geth(b.a,a),geth(b.b,a));
swap(minn.second.a,minn.second.b);
ans=min(ans,minn);
if(cross(ans.second,segment(point(-SS,SS),point(SS,SS))))return;
if(cross(ans.second,segment(point(SS,-SS),point(SS,SS))))return;
if(cross(ans.second,segment(point(-SS,-SS),point(SS,-SS))))return;
if(cross(ans.second,segment(point(-SS,-SS),point(-SS,SS))))return;
if(cross(ans.second,segment(point(-SS,-SS),point(SS,SS))))return;
if(cross(ans.second,segment(point(-SS,SS),point(SS,-SS))))return;
bool flag=cross(segment(a.a,ans.second.a),line)^cross(ans.second,line)^cross(segment(ans.second.b,b.a),line);
f[i][j][flag]=f[j][i][flag]=ans.first;
}
int main(){
cin>>n>>S;
for(int i=1;i<=n;i++){
cin>>a[i].a.x>>a[i].a.y>>a[i].b.x>>a[i].b.y;
}
line=segment(point(0.0,0.0),point(10000.0,10000.0*((nsc()%10000)/10000.0*pi/2)));
SS=S-eps*100;
a[++n]=segment(point(S,S+eps),point(S+eps,S));
a[++n]=segment(point(-S-eps,S),point(-S,S+eps));
a[++n]=segment(point(-S-eps,-S),point(-S,-S-eps));
a[++n]=segment(point(S,-S-eps),point(S+eps,-S));
for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)f[i][j][0]=f[i][j][1]=inf;
for(int i=1;i<=n;i++)f[i][i][0]=0;
for(int i=1;i<=n;i++){
for(int j=i+1;j<=n;j++){
solve(a[i],a[j],i,j);
}
}
for(int k=1;k<=n;k++){
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
for(int p=0;p<2;p++){
for(int q=0;q<2;q++){
f[i][j][p^q]=min(f[i][j][p^q],f[i][k][p]+f[k][j][q]);
}
}
}
}
}
double ans=inf;
for(int i=1;i<=n;i++)ans=min(ans,f[i][i][1]);
cout<<fixed<<setprecision(10)<<ans<<endl;
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】