TopCoder SRM 355 Div1 Medium Tetrahedron
問題
空間上に4点がある。
それぞれの距離がd[i][j]によって与えられる。
この距離を満たす4点は存在するか、するならYESを、しないならNOを答えよ。
制約条件
dは4行4列の対称行列
d[i][j]≦10
方針
一点は原点に固定してよい。
2点目はx軸上の正の部分に取ってよい。
3点目はxy平面上に取る。
連立方程式を解けば、3点目の座標(x[2],y[2])が求まる。
4点目の座標を(x[3],y[3],z[3])すると、連立方程式が3つ立つ。
連立方程式が正しい解を持てば、4点目の座標が具体的に求まり、4点が存在することがわかる。
ソースコード
inline double sq(double x){return x*x;} class Tetrahedron { public: string exists(vector <string> dist) { vector<vi> d(4); rep(i,4){ stringstream ss(dist[i]); int x; while(ss>>x)d[i].pb(x); } double x[4],y[4],z[4]; x[0]=y[0]=z[0]=0; x[1]=d[0][1]; y[1]=z[1]=0; x[2]=(sq(x[1])-sq(d[1][2])+sq(d[0][2]))/(2*x[1]); y[2]=sq(d[0][2])-sq(x[2]); if(y[2]<0)return "NO"; y[2]=sqrt(y[2]); z[2]=0; x[3]=(sq(x[1])-sq(d[1][3])+sq(d[0][3]))/(2*x[1]); y[3]=(sq(y[2])-sq(d[2][3])+sq(d[0][3])+sq(x[3]-x[2])-sq(x[3]))/(2*y[2]); z[3]=sq(d[0][3])-sq(x[3])-sq(y[3]); if(z[3]<0)return "NO"; z[3]=sqrt(z[3]); rep(i,4)rep(j,4) if(abs(sq(x[i]-x[j])+sq(y[i]-y[j])+sq(z[i]-z[j])-sq(d[i][j]))>EPS) return "NO"; rep(i,4)cerr<<x[i]<<" "<<y[i]<<" "<<z[i]<<endl; return "YES"; } };