傻逼题。我从来没见过eps这样的。。。

打破了我对计算几何美好的幻想。

eps=1e-6=>wa3  eps=1e-8->wa2  eps 1e-4->AC

真的自闭,真的猜不到eps要设成1e-4,最后看了先杭电的代码,发现他们是1e-4,我就改了下,然后????过了????

nmsl

nmsl

nmsl

思路正确无比。赛后发现板子错了,把板子删了,tle3,把三分套三分换成了三分+板子,就开始无限WA制了

精简一下就是一句话:求线段到三角形的距离。

前置技能:三分,点到三角形的距离,点到线段的距离,点到平面的投影,点是否在三角形内

然后就没了。赛时-13赛后+37

 #include <bits/stdc++.h>
using namespace std;
typedef double db;
const db eps = 1e-;
const db pi = acos(-);
int sign(db k){if(k>eps)return ;else if(k<-eps)return -;return ;}
int cmp(db k1,db k2){return sign(k1-k2);}
int inmid(db k1,db k2,db k3){return sign(k1-k3)*sign(k2-k3)<=;}// k3 在 [k1,k2] 内
struct point{
db x,y,z;
point operator + (point k1){return (point){x+k1.x,y+k1.y,z+k1.z};}
point operator - (point k1){return (point){x-k1.x,y-k1.y,z-k1.z};}
point operator * (db k1){return (point){x*k1,y*k1,z*k1};}
point operator / (db k1){return (point){x/k1,y/k1,z/k1};}
db length()const {return sqrt(x*x+y*y+z*z);}
db len2()const {return x*x+y*y+z*z;}
};
point det(const point &a,const point &b){
return point{a.y*b.z-a.z*b.y,a.z*b.x-a.x*b.z,a.x*b.y-a.y*b.x};
}
db dis(const point &a,const point &b){//距离
return sqrt(pow(a.x-b.x,)+pow(a.y-b.y,)+pow(a.z-b.z,));
}
struct line{
point p[];
line (point k1,point k2){p[]=k1; p[]=k2;}
point& operator [] (int k){return p[k];}
};
db dot(point k1,point k2){return k1.x*k2.x+k1.y*k2.y+k1.z*k2.z;}
int dot_online_in(point p,line l){//点在线段上,包括端点
return sign(det(p-l[],p-l[]).length())==&&(l[].x-p.x)*(l[].x-p.x)<eps&&
(l[].y-p.y)*(l[].y-p.y)<eps&&(l[].z-p.z)*(l[].z-p.z)<eps;
}
struct plane{
point p[];
plane(point k1,point k2,point k3){p[]=k1,p[]=k2,p[]=k3;}
point& operator [] (int k){return p[k];}
};
point pvec(point s1,point s2,point s3){
return det(s1-s2,s2-s3);
}
point pvec(plane s){return pvec(s[],s[],s[]);}
int dot_inplane_in(point p,plane s){
return sign(det(s[]-s[],s[]-s[]).length()-det(p-s[],p-s[]).length()-
det(p-s[],p-s[]).length()-det(p-s[],p-s[]).length())==;
}
int sameside(point p1,point p2,plane s){//两点在平面同侧
// point tmp = pvec(s);
return dot(pvec(s),p1-s[])*dot(pvec(s),p2-s[])>eps;
}
int intersect_in(line l,plane s){//线段和三角形是否有交点包含边界
return !sameside(l[],l[],s)&&
!sameside(s[],s[],plane{l[],l[],s[]})&&
!sameside(s[],s[],plane{l[],l[],s[]})&&
!sameside(s[],s[],plane{l[],l[],s[]});
}
point intersection(line l,plane s){//直线与平面的交点
point ret = pvec(s);
db t = ((ret.x*(s[].x-l[].x)+ret.y*(s[].y-l[].y))+ret.z*(s[].z-l[].z))/
((ret.x*(l[].x-l[].x)+ret.y*(l[].y-l[].y))+ret.z*(l[].z-l[].z));
ret = l[]+(l[]-l[])*t;return ret;
}
int t;
point p[];
int check(plane a,plane b){//check 0;
bool f=;
if(intersect_in({a[],a[]},b))f=;
if(intersect_in({a[],a[]},b))f=;
if(intersect_in({a[],a[]},b))f=;
if(intersect_in({b[],b[]},a))f=;
if(intersect_in({b[],b[]},a))f=;
if(intersect_in({b[],b[]},a))f=;
return f;
}
db slove(plane a,plane b){//b三个点到a的距离
db ans = 1e18;
point x = pvec(a);
line s0 = {b[],b[]+x};
point xx = intersection(s0,a);
if(dot_inplane_in(xx,a))
ans = min(ans,(xx-b[]).length());
line s1 = {b[],b[]+x};
xx = intersection(s1,a);
if(dot_inplane_in(xx,a))
ans = min(ans,(xx-b[]).length());
line s2 = {b[],b[]+x};
xx = intersection(s2,a);
if(dot_inplane_in(xx,a))
ans = min(ans,(xx-b[]).length());
return ans;
}
db ptoline(point p,line l){//点到直线的距离
return (det(p-l[],l[]-l[])/dis(l[],l[])).length();
}
point proj(point k1,point k2,point q){ // q 到直线 k1,k2 的投影
point k=k2-k1; return k1+k*(dot(q-k1,k)/k.len2());
}
int inmid(point k1,point k2,point k3){
return inmid(k1.x,k2.x,k3.x)&&inmid(k1.y,k2.y,k3.y)&&inmid(k1.z,k2.z,k3.z);
}
db slove2(point a,line b){//点到线段的距离
point v1=b[]-b[],v2=a-b[],v3=a-b[];
if(sign(dot(v1,v2)<))return v2.length();
else if(sign(dot(v1,v3))>)return v3.length();
else return det(v1,v2).length()/v1.length();
// point x = proj(b[0],b[1],a);
// if(dot_online_in(x,b))
// return (a-x).length();
// return min((a-b[0]).length(),(a-b[1]).length());
}
db dis_point_plane(point a,plane p){
point xx = pvec(p);
line l = {a,a+xx};
point xxx = intersection(l,p);
if(dot_inplane_in(xxx,p))
return (a-xxx).length();
return min(min(slove2(a,{p[],p[]}),slove2(a,{p[],p[]})),slove2(a,{p[],p[]}));
}
db slove3(line a,plane b){
point l=a[],r=a[];
for(int i=;i<;i++){
point mid = (l+r)/,lm=(l+mid)/,rm=(r+mid)/;
if(dis_point_plane(lm,b)<=dis_point_plane(rm,b)){
r=rm;
} else
l=lm;
}
return dis_point_plane(l,b);
}
double x,y,z;
int main(){
scanf("%d",&t);
while (t--){
for(int i=;i<=;i++){
scanf("%lf%lf%lf",&x,&y,&z);
p[i]={x,y,z};
}
plane a = {p[],p[],p[]},b = {p[],p[],p[]};
// if(check(a,b)){
// printf("%.11f\n",0.0);
// }else{
db ans = 1e18;
// ans = min(ans,slove(a,b));
// ans = min(ans,slove(b,a));
// for(int i=0;i<3;i++) {
// for(int k=0;k<3;k++) {
// point l=a[i],r=a[(i+1)%3],lm,rm;
// line t=(line){b[k],b[(k+1)%3]};
// for(int j=0;j<90;j++) {
// lm=l+(r-l)/3,rm=r-(r-l)/3;
// if(slove2(lm,t)<=slove2(rm,t)) r=rm;
// else l=lm;
// }
// ans=std::min(ans,slove2(r,t));
// }
// }
for(int i=;i<;i++){
ans = min(ans,slove3({a[i],a[(i+)%]},b));
ans = min(ans,slove3({b[i],b[(i+)%]},a));
}
printf("%.11f\n",ans);
// }
}
}
/**
1
0 0 0 1 0 0 0 1 0
2 2 1 3 2 1 2 3 1
*/
05-11 17:46