Solution 首先发现一个性质,这个
2024-06-05 20:00:37
发布于:广东
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef double db;
struct vec{
ll x,y;
vec(ll _x=0, ll _y=0):x(_x),y(_y){}
inline vec operator + (vec other){return vec(x+other.x,y+other.y);}
inline vec operator - (vec other){return vec(x-other.x,y-other.y);}
inline ll operator * (vec other){return xother.x+yother.y;}
inline ll operator ^ (vec other){return xother.y-yother.x;}
inline void print(){cout<<x<<' '<<y<<' ';}
};
inline db sq(db w){return ww;}
inline db len(vec x){return sqrt(sq(x.x)+sq(x.y));}
constexpr db eps=1e-10;
int n,q;vec p[100005];
inline db cmax(db a,db b){
if(fabs(a+1)<eps) return b;
if(fabs(b+1)<eps) return a;
return min(a,b);
}
inline bool chkrt(vec A,vec B,vec C){return ((B-A)^(C-A))<0;}
inline bool chkrrt(vec A,vec B,vec C){return !chkrt(A,C,B);}
struct node{
ll x,y;int id;
node(ll _x=0,ll _y=0,int _id=0):x(_x),y(_y),id(_id){}
inline bool operator < (const node &other){return xother.x?y<other.y:x<other.x;}
}z[100005];
pair<vec,vec> SolveCutPoint(vec A){
// A.print();cout<<"-> ";
int l=1,r=n,ans=-1;
auto w=node(A.x,A.y,0);
auto ww=*lower_bound(z+1,z+n+1,w);
// cout<<ww.x<<' '<<ww.y<<' '<<ww.id<<'\n';
if(A.xww.x&&A.y==ww.y){
int k=ww.id;
if(chkrt(A,p[k-1],p[k+1])) return make_pair(p[k+1],p[k-1]);
else return make_pair(p[k-1],p[k+1]);
}
// for(int i=1;i<=n;i++) cout<<chkrt(A,p[i],p[i+1]);cout<<'\n';
if(!chkrt(A,p[1],p[2])&&!chkrt(A,p[1],p[0])) ans=1;
while(l<r){
int m=l+r+1>>1;
// cout<<l<<' '<<m<<' '<<r<<'\n';
if(!chkrt(A,p[m],p[m+1])&&!chkrt(A,p[m],p[m-1])){ans=m;break;}
if(chkrt(A,p[l],p[l+1])){
if(!chkrt(A,p[m],p[m+1])) r=m-1;
else if(chkrt(A,p[l],p[m])) l=m;
else r=m-1;
}
else{
if(chkrt(A,p[m],p[m+1])) l=m;
else if(!chkrt(A,p[l],p[m])) l=m;
else r=m-1;
}
}
// for(int i=1;i<=n;i++) cout<<chkrrt(A,p[i],p[i+1]);cout<<'\n';
int ansb=-1;l=1,r=n;
if(chkrrt(A,p[1],p[2])&&chkrrt(A,p[1],p[0])) ansb=1;
while(l<r){
int m=l+r+1>>1;
// cout<<l<<" "<<m<<' '<<r<<endl;
if(chkrrt(A,p[m],p[m+1])&&chkrrt(A,p[m],p[m-1])){ansb=m;break;}
if(!chkrt(A,p[l],p[l+1])){
if(chkrt(A,p[m],p[m+1])) r=m-1;
else if(!chkrt(A,p[l],p[m])) l=m;
else r=m-1;
}
else{
if(!chkrt(A,p[m],p[m+1])) l=m;
else if(chkrt(A,p[l],p[m])) l=m;
else r=m-1;
}
}
assert(ans!=-1);
assert(ansb!=-1);
// p[ans].print();p[ansb].print();cout<<'\n';
return make_pair(p[ans],p[ansb]);
}
inline int sgn(db x){
if(fabs(x)<eps) return 0;
if(x>0) return 1;
return -1;
}
inline bool Mid(vec A,vec B,vec C,vec D){
// A.print(),B.print(),C.print(),D.print();
// cout<<(!chkrt(A,D,B))<<(!chkrt(A,C,D))<<'\n';
return !chkrt(A,D,B)||!chkrt(A,C,D);
}
inline db Solvelen(vec Ax,vec Ay,vec Bx,vec By){
// Ax.print();Ay.print();Bx.print();By.print();cout<<'\n';
db Ak=(Ax.y-Ay.y)1.0/(Ax.x-Ay.x);db Ab=Ax.y-Ax.xAk;
db Bk=(Bx.y-By.y)1.0/(Bx.x-By.x);db Bb=Bx.y-Bx.xBk;
if(fabs(Ak-Bk)<eps) return -1;
db X=(Bb-Ab)/(Ak-Bk);
db Y=AkX+Ab;
if(Ax.xAy.x){
if(Bx.xBy.x) return -1;
X=Ax.x;Y=BkX+Bb;
}
else if(Bx.x==By.x)X=Bx.x,Y=AkX+Ab;
// cout<<Ak<<' '<<Ab<<' '<<Bk<<' '<<Bb<<' '<<X<<' '<<Y<<'\n';
if(sgn(Ax.x-X)==sgn(Ay.x-Ax.x)&&fabs(Ax.x-X)>eps) return -1;
if(sgn(Bx.x-X)==sgn(By.x-Bx.x)&&fabs(Bx.x-X)>eps) return -1;
//vec w(X,Y);
//Ax.print();Ay.print();Bx.print();By.print();w.print();cout<<'\n';
return sqrt(sq(Ax.x-X)+sq(Ax.y-Y))+sqrt(sq(Bx.x-X)+sq(Bx.y-Y));
}
inline db solve(){
vec A,B;cin>>A.x>>A.y>>B.x>>B.y;
pair<vec,vec> p1=SolveCutPoint(A),p2=SolveCutPoint(B);
if(Mid(A,p1.first,p1.second,B)||Mid(B,p2.first,p2.second,A)) return len(A-B);
return cmax(cmax(Solvelen(A,p1.first,B,p2.first),Solvelen(A,p1.first,B,p2.second)),
cmax(Solvelen(A,p1.second,B,p2.first),Solvelen(A,p1.second,B,p2.second)));
}
int main(){
ios::sync_with_stdio(0),cin.tie(0),cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
cin>>p[i].x>>p[i].y;
}
p[n+1]=p[1];p[0]=p[n];
for(int i=1;i<=n;i++) z[i]=node(p[i].x,p[i].y,i);
sort(z+1,z+n+1);
cin>>q;while(q--){
db ww=solve();
printf("%.10lf\n",ww);
}
}
这里空空如也
有帮助,赞一个