欢迎大家访问我的老师的OJ———caioj.cn
题面描述
思路
因为一个球体的球面上的所有点到圆心的距离相等,因此只需求出一个点( x 1 , x 2 , x 3 , . . . . . . , x n x_1,x_2,x_3,......,x_n x1,x2,x3,......,xn),使得:
∑ j = 1 n ( a i , j − x j ) 2 = C ( i ∈ [ 1 , n + 1 ] ) \large\sum_{j=1}^{n}(a_{i,j}-x_j)^2=C (i\in[1,n+1]) j=1∑n(ai,j−xj)2=C(i∈[1,n+1])
其中 C C C为常量,球面上第 i i i个已知点的坐标为( a i , 1 , a i , 2 , . . . . . . , a i , n a_{i,1},a_{i,2},......,a_{i,n} ai,1,ai,2,......,ai,n)。
如何将这个 n + 1 n+1 n+1个 n n n元二次方程组转化为线性方程组呢?观察到,方程右边都有 C C C
我们不妨两两做差,将 C C C消掉。
得到:
∑
j
=
1
n
(
a
i
,
j
2
−
a
i
+
1
,
j
2
−
2
x
j
(
a
i
,
j
−
a
i
+
1
,
j
)
)
=
0
(
i
∈
[
1
,
n
]
)
\large\sum_{j=1}^{n}(a_{i,j}^2-a_{i+1,j}^2-2x_j(a_{i,j}-a_{i+1,j}))=0(i\in[1,n])
j=1∑n(ai,j2−ai+1,j2−2xj(ai,j−ai+1,j))=0(i∈[1,n])
将变量放左,常量放右,有:
∑
j
=
1
n
2
(
a
i
,
j
−
a
i
+
1
,
j
)
x
j
=
∑
j
=
1
n
(
a
i
,
j
2
−
a
i
+
1
,
j
2
)
(
i
∈
[
1
,
n
]
)
\large\sum_{j=1}^n2(a_{i,j}-a_{i+1,j})x_j=\sum_{j=1}^n(a_{i,j}^2-a_{i+1,j}^2)(i\in[1,n])
j=1∑n2(ai,j−ai+1,j)xj=j=1∑n(ai,j2−ai+1,j2)(i∈[1,n])
这就是一个线性方程组了。
[ 2 ( a 1 , 1 − a 2 , 1 ) 2 ( a 1 , 2 − a 2 , 2 ) . . . 2 ( a 1 , n − a 2 , n ) ∑ j = 1 n ( a 1 , j 2 − a 2 , j 2 ) 2 ( a 2 , 1 − a 3 , 1 ) 2 ( a 2 , 2 − a 3 , 2 ) . . . 2 ( a 2 , n − a 3 , n ) ∑ j = 1 n ( a 2 , j 2 − a 3 , j 2 ) ⋮ ⋮ ⋱ ⋮ ⋮ 2 ( a n , 1 − a n + 1 , 1 ) 2 ( a n , 2 − a n + 1 , 2 ) . . . 2 ( a n , n − a n + 1 , n ) ∑ j = 1 n ( a n , j 2 − a n + 1 , j 2 ) ] \begin{bmatrix}2(a_{1,1}-a_{2,1})&2(a_{1,2}-a_{2,2})&...&2(a_{1,n}-a_{2,n})&\large\sum_{j=1}^n(a_{1,j}^2-a_{2,j}^2)\\2(a_{2,1}-a_{3,1})&2(a_{2,2}-a_{3,2})&...&2(a_{2,n}-a_{3,n})&\large\sum_{j=1}^n(a_{2,j}^2-a_{3,j}^2)\\\vdots&\vdots&\ddots&\vdots&\vdots\\2(a_{n,1}-a_{n+1,1})&2(a_{n,2}-a_{n+1,2})&...&2(a_{n,n}-a_{n+1,n})&\large\sum_{j=1}^n(a_{n,j}^2-a_{n+1,j}^2)\end{bmatrix} ⎣⎢⎢⎢⎢⎡2(a1,1−a2,1)2(a2,1−a3,1)⋮2(an,1−an+1,1)2(a1,2−a2,2)2(a2,2−a3,2)⋮2(an,2−an+1,2)......⋱...2(a1,n−a2,n)2(a2,n−a3,n)⋮2(an,n−an+1,n)∑j=1n(a1,j2−a2,j2)∑j=1n(a2,j2−a3,j2)⋮∑j=1n(an,j2−an+1,j2)⎦⎥⎥⎥⎥⎤
高斯消元求 x j x_j xj即可。
AC code
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#define eps 1e-10
using namespace std;
double a[20][20],c[20][20],b[20];int n;
void gauss()
{
for(int i=1;i<=n;i++)
{
int x=i;
while(fabs(c[x][i])<eps&&x<=n)x++;
for(int j=1;j<=n;j++)swap(c[x][j],c[i][j]);swap(b[x],b[i]);
for(int k=1;k<=n;k++)
{
if(k==i)continue;
b[k]-=c[k][i]/c[i][i]*b[i];
for(int j=n;j>=i;j--)c[k][j]-=c[k][i]/c[i][i]*c[i][j];
}
}
for(int i=1;i<n;i++)printf("%.3lf ",b[i]/c[i][i]);
printf("%.3lf\n",b[n]/c[n][n]);
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n+1;i++)
for(int j=1;j<=n;j++)
scanf("%lf",&a[i][j]);
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
{
c[i][j]=2*(a[i][j]-a[i+1][j]);
b[i]+=a[i][j]*a[i][j]-a[i+1][j]*a[i+1][j];
}
gauss();
return 0;
}