洛谷 P4035 [JSOI2008]球形空间产生器

    科技2026-01-28  10

    题目链接: P4035 [JSOI2008]球形空间产生器

    题目大意: 在 n ( n ≤ 10 ) n(n\leq10) n(n10)维空间中,给出一个 n n n维球体上的 n + 1 n+1 n+1个点,求这个球的球心坐标。

    题目分析: 考虑将第 n n n维中,将第 i i i个点的第 j j j维表示为 x i j x_{ij} xij,设球心的坐标为 x 0 k x_{0k} x0k则对于这 n n n个点构成的方程组为 { ( x 11 − x 01 ) 2 + ( x 12 − x 02 ) 2 + . . . + ( x 1 n − x 0 n ) 2 = r 2 ( x 21 − x 01 ) 2 + ( x 22 − x 02 ) 2 + . . . + ( x 2 n − x 0 n ) 2 = r 2 . . . . . ( x n 1 − x 01 ) 2 + ( x n 2 − x 02 ) 2 + . . . + ( x n n − x 0 n ) 2 = r 2 \left\{ \begin{array}{l} (x_{11}-x_{01})^2+(x_{12}-x_{02})^2+...+(x_{1n}-x_{0n})^2=r^2\\ (x_{21}-x_{01})^2+(x_{22}-x_{02})^2+...+(x_{2n}-x_{0n})^2=r^2\\ ..... \\ (x_{n1}-x_{01})^2+(x_{n2}-x_{02})^2+...+(x_{nn}-x_{0n})^2=r^2\\ \end{array} \right. (x11x01)2+(x12x02)2+...+(x1nx0n)2=r2(x21x01)2+(x22x02)2+...+(x2nx0n)2=r2.....(xn1x01)2+(xn2x02)2+...+(xnnx0n)2=r2 把括号拆开 { x 11 2 − 2 x 11 x 01 + x 01 2 + . . . + x 1 n 2 − 2 x 1 n x 0 n + x 0 n 2 = r 2 x 21 2 − 2 x 21 x 01 + x 01 2 + . . . + x 2 n 2 − 2 x 2 n x 0 n + x 0 n 2 = r 2 . . . . . . x n 1 2 − 2 x n 1 x 01 + x 01 2 + . . . + x n n 2 − 2 x n n x 0 n + x 0 n 2 = r 2 \left\{ \begin{array}{l} x_{11}^2-2x_{11}x_{01}+x_{01}^2+...+x_{1n}^2-2x_{1n}x_{0n}+x_{0n}^2=r^2\\ x_{21}^2-2x_{21}x_{01}+x_{01}^2+...+x_{2n}^2-2x_{2n}x_{0n}+x_{0n}^2=r^2\\ ......\\ x_{n1}^2-2x_{n1}x_{01}+x_{01}^2+...+x_{nn}^2-2x_{nn}x_{0n}+x_{0n}^2=r^2\\ \end{array} \right. x1122x11x01+x012+...+x1n22x1nx0n+x0n2=r2x2122x21x01+x012+...+x2n22x2nx0n+x0n2=r2......xn122xn1x01+x012+...+xnn22xnnx0n+x0n2=r2 将相邻的式子作差 ( ① − ② , ② − ③ . . . ) (①-②,②-③...) (,...)得到 n n n个方程 { 2 ( x 21 − x 11 ) x 01 + . . . + 2 ( x 2 n − x 1 n ) x 0 n = x 11 2 − x 21 2 + . . . + x 1 n 2 − x 2 n 2 2 ( x 31 − x 21 ) x 01 + . . . + 2 ( x 3 n − x 2 n ) x 0 n = x 21 2 − x 31 2 + . . . + x 2 n 2 − x 3 n 2 . . . 2 ( x n 1 − x ( n − 1 ) 1 ) x 01 + . . . + 2 ( x n n − x ( n − 1 ) n ) x 0 n = x ( n − 1 ) 1 2 − x n 1 2 + . . . + x ( n − 1 ) n 2 − x n n 2 \left\{ \begin{array}{l} 2(x_{21}-x_{11})x_{01}+...+2(x_{2n}-x_{1n})x_{0n}=x_{11}^2-x_{21}^2+...+x_{1n}^2-x_{2n}^2\\ 2(x_{31}-x_{21})x_{01}+...+2(x_{3n}-x_{2n})x_{0n}=x_{21}^2-x_{31}^2+...+x_{2n}^2-x_{3n}^2\\ ...\\ 2(x_{n1}-x_{(n-1)1})x_{01}+...+2(x_{nn}-x_{(n-1)n})x_{0n}=x_{(n-1)1}^2-x_{n1}^2+...+x_{(n-1)n}^2-x_{nn}^2\\ \end{array} \right. 2(x21x11)x01+...+2(x2nx1n)x0n=x112x212+...+x1n2x2n22(x31x21)x01+...+2(x3nx2n)x0n=x212x312+...+x2n2x3n2...2(xn1x(n1)1)x01+...+2(xnnx(n1)n)x0n=x(n1)12xn12+...+x(n1)n2xnn2 到这里,题目就变成了一个高斯消元的裸题,代码如下: 题目代码:

    #include<stdio.h> #include<algorithm> #include<string.h> #define swap(a,b)(a+=b,b=a-b,a=a-b) using namespace std; double x[100][100],m[100][100]; int n,flag; void Gauss(){ for(int i=1;i<=n;i++){ if(!m[i][i]){ flag=1; for(int j=i;j<=n;j++)if(m[j][i]){ flag=0; for(int k=1;k<=n+1;k++) swap(m[i][k],m[j][k]); break; } } for(int j=1;j<=n;j++)if(i^j){ double ns=m[j][i]/m[i][i]; for(int k=1;k<=n+1;k++) m[j][k]-=m[i][k]*ns; } } for(int i=1;i<=n;i++) m[i][n+1]/=m[i][i]; for(int i=1;i<=n;i++) printf("%.3f ",m[i][n+1]); } int main() { scanf("%d",&n); for(int i=1;i<=n+1;i++) for(int j=1;j<=n;j++) scanf("%lf",&x[i][j]); for(int i=2;i<=n+1;i++) for(int j=1;j<=n;j++){ m[i-1][j]=2*(x[i][j]-x[i-1][j]); m[i-1][n+1]+=(x[i][j]*x[i][j])-(x[i-1][j]*x[i-1][j]); } Gauss(); return 0; }
    Processed: 0.018, SQL: 10