设球心的坐标为
(
x
1
,
x
2
,
.
.
.
,
x
n
)
(x_1,x_2,...,x_n)
(x1,x2,...,xn),可以列出方程:
{
(
a
1
,
1
−
x
1
)
2
+
(
a
1
,
2
−
x
2
)
2
+
.
.
.
+
(
a
1
,
n
−
x
n
)
2
=
k
(
a
2
,
1
−
x
1
)
2
+
(
a
2
,
2
−
x
2
)
2
+
.
.
.
+
(
a
2
,
n
−
x
n
)
2
=
k
.
.
.
(
a
n
+
1
,
1
−
x
1
)
2
+
(
a
n
+
1
,
2
−
x
2
)
2
+
.
.
.
+
(
a
n
+
1
,
n
−
x
n
)
2
=
k
\begin{cases} (a_{1,1}-x_1)^2+(a_{1,2}-x_2)^2+...+(a_{1,n}-x_n)^2=k\\ (a_{2,1}-x_1)^2+(a_{2,2}-x_2)^2+...+(a_{2,n}-x_n)^2=k\\ ...\\ (a_{n+1,1}-x_1)^2+(a_{n+1,2}-x_2)^2+...+(a_{n+1,n}-x_n)^2=k \end{cases}
⎩⎪⎪⎪⎨⎪⎪⎪⎧(a1,1−x1)2+(a1,2−x2)2+...+(a1,n−xn)2=k(a2,1−x1)2+(a2,2−x2)2+...+(a2,n−xn)2=k...(an+1,1−x1)2+(an+1,2−x2)2+...+(an+1,n−xn)2=k
是个二次方程,还有个
k
k
k,不太可解。把方程展开得:
{
(
x
1
2
+
x
2
2
+
.
.
.
+
x
n
2
)
−
2
(
x
1
a
1
,
1
+
x
2
a
1
,
2
+
.
.
.
+
x
n
a
1
,
n
)
+
(
a
1
,
1
2
+
a
1
,
2
2
+
.
.
.
+
a
1
,
n
2
)
=
k
(
x
1
2
+
x
2
2
+
.
.
.
+
x
n
2
)
−
2
(
x
1
a
2
,
1
+
x
2
a
2
,
2
+
.
.
.
+
x
n
a
2
,
n
)
+
(
a
2
,
1
2
+
a
2
,
2
2
+
.
.
.
+
a
2
,
n
2
)
=
k
.
.
.
(
x
1
2
+
x
2
2
+
.
.
.
+
x
n
2
)
−
2
(
x
1
a
n
+
1
,
1
+
x
2
a
n
+
1
,
2
+
.
.
.
+
x
n
a
n
+
1
,
n
)
+
(
a
n
+
1
,
1
2
+
a
n
+
1
,
2
2
+
.
.
.
+
a
n
+
1
,
n
2
)
=
k
\begin{cases} ({x_1}^2+{x_2}^2+...+{x_n}^2)-2(x_1a_{1,1}+x_2a_{1,2}+...+x_na_{1,n})+({a_{1,1}}^2+{a_{1,2}}^2+...+{a_{1,n}}^2)=k\\ ({x_1}^2+{x_2}^2+...+{x_n}^2)-2(x_1a_{2,1}+x_2a_{2,2}+...+x_na_{2,n})+({a_{2,1}}^2+{a_{2,2}}^2+...+{a_{2,n}}^2)=k\\ ...\\ ({x_1}^2+{x_2}^2+...+{x_n}^2)-2(x_1a_{n+1,1}+x_2a_{n+1,2}+...+x_na_{n+1,n})+({a_{n+1,1}}^2+{a_{n+1,2}}^2+...+{a_{n+1,n}}^2)=k\\ \end{cases}
⎩⎪⎪⎪⎨⎪⎪⎪⎧(x12+x22+...+xn2)−2(x1a1,1+x2a1,2+...+xna1,n)+(a1,12+a1,22+...+a1,n2)=k(x12+x22+...+xn2)−2(x1a2,1+x2a2,2+...+xna2,n)+(a2,12+a2,22+...+a2,n2)=k...(x12+x22+...+xn2)−2(x1an+1,1+x2an+1,2+...+xnan+1,n)+(an+1,12+an+1,22+...+an+1,n2)=k
设
K
i
=
[
(
a
i
,
1
2
+
a
i
,
2
2
+
.
.
.
+
a
i
,
n
2
)
−
(
a
i
+
1
,
1
2
+
a
i
+
1
,
2
2
+
.
.
.
+
a
i
+
1
,
n
2
)
]
÷
2
K_i=[({a_{i,1}}^2+{a_{i,2}}^2+...+{a_{i,n}}^2)-({a_{i+1,1}}^2+{a_{i+1,2}}^2+...+{a_{i+1,n}}^2)]\div2
Ki=[(ai,12+ai,22+...+ai,n2)−(ai+1,12+ai+1,22+...+ai+1,n2)]÷2 ,
n
+
1
n+1
n+1 个方程,两两相减可得:
{
x
1
(
a
1
,
1
−
a
2
,
1
)
+
x
2
(
a
1
,
2
−
a
2
,
2
)
+
.
.
.
+
x
n
(
a
1
,
n
−
a
2
,
n
)
=
K
1
x
1
(
a
2
,
1
−
a
3
,
1
)
+
x
2
(
a
2
,
2
−
a
3
,
2
)
+
.
.
.
+
x
n
(
a
2
,
n
−
a
3
,
n
)
=
K
2
.
.
.
x
1
(
a
n
,
1
−
a
n
+
1
,
1
)
+
x
2
(
a
n
,
2
−
a
n
+
1
,
2
)
+
.
.
.
+
x
n
(
a
n
,
n
−
a
n
+
1
,
n
)
=
K
n
\begin{cases} x_1(a_{1,1}-a_{2,1})+x_2(a_{1,2}-a_{2,2})+...+x_n(a_{1,n}-a_{2,n})=K_1\\ x_1(a_{2,1}-a_{3,1})+x_2(a_{2,2}-a_{3,2})+...+x_n(a_{2,n}-a_{3,n})=K_2\\ ...\\ x_1(a_{n,1}-a_{n+1,1})+x_2(a_{n,2}-a_{n+1,2})+...+x_n(a_{n,n}-a_{n+1,n})=K_n\\ \end{cases}
⎩⎪⎪⎪⎨⎪⎪⎪⎧x1(a1,1−a2,1)+x2(a1,2−a2,2)+...+xn(a1,n−a2,n)=K1x1(a2,1−a3,1)+x2(a2,2−a3,2)+...+xn(a2,n−a3,n)=K2...x1(an,1−an+1,1)+x2(an,2−an+1,2)+...+xn(an,n−an+1,n)=Kn
用高斯消元求解。高斯消元可见:我的文章。
//P4035
#include <bits/stdc++.h>
using namespace std;
const double eps = 1e-6;
const int N = 15;
double a[N][N], mat[N][N], sum[N];
int n;
int gauss(){
int c, r;//c列,r行
for(c = 0, r = 0; c < n; ++ c){
int tmp = r;
//找到绝对值最大的行,为了把 0 的行移到最下面去不管它,最后判断
for(int i = r; i < n; ++ i) if(fabs(mat[i][c]) > fabs(mat[tmp][c])) tmp = i;
if(fabs(mat[tmp][c]) < eps) continue;
for(int i = c; i <= n; ++ i) swap(mat[tmp][i], mat[r][i]);
for(int i = n; i >= c; -- i) mat[r][i] /= mat[r][c];
for(int i = r+1; i < n; ++ i) if(fabs(mat[i][c]) > eps)
for(int j = n; j >= c; -- j) mat[i][j] -= mat[r][j] * mat[i][c];
++ r;
}
if(r < n){
for(int i = r; i < n; ++ i) if(fabs(mat[i][n]) > eps) return 2;//no solution
return 1;//infinity
}
for(int i = n-1; i>=0; -- i) for(int j = i+1; j < n; ++ j) mat[i][n] -= mat[i][j] * mat[j][n];
return 0;
}
int main(){
scanf("%d", &n);
for(int i = 0; i <= n; ++ i)
for(int j = 0; j < n; ++ j)
scanf("%lf", &a[i][j]), sum[i] += a[i][j]*a[i][j];
for(int i = 0; i < n; ++ i)
for(int j = 0; j < n; ++ j)
mat[i][j] = (a[i][j] - a[i+1][j])*2;
for(int i = 0; i < n; ++ i)
mat[i][n] = (sum[i] - sum[i+1]);
gauss();
for(int i = 0; i < n; ++ i)
printf("%.3lf ", mat[i][n]);
return 0;
}
当然这题还可以用模拟退火解,这里就不再讲解。