トピックの説明
n 次元空間に固体の球を生成する球空間ジェネレーターがあります。さて、あなたはこの n 次元の球の中に閉じ込められています。球上の n+1 個の点の座標しか知りません。破壊するには、この n 次元の球の中心の座標をできるだけ早く決定する必要があります。この球状空間を利用してデバイスを生成します。
入力フォーマット
最初の行は整数 (1≤N≤10) です。次の n+1 行には、各行に n 個の実数があり、球上の点の n 次元座標を表します。各実数は小数点以下 6 桁までの精度があり、その絶対値は 20000 を超えません。
出力フォーマット
球の中心の n 次元座標 (n 個の実数) を順番に示す 1 本の線があり、2 つの実数はスペースで区切られています。各実数は小数点以下 3 桁まで正確です。データには解決策があることが保証されています。回答は、スコア付けされる標準出力とまったく同じである必要があります。
解析:
球の中心が球の中心から点までの距離と同じであるとします。2 つの隣接する方程式を減算すると、未知数が左にシフトします。
円の中心の位置を取得するために解くことができる n 個の未知の項目と n 個の方程式があります。
#include<bits/stdc++.h>
using namespace std;
inline double read() {
char ss = getchar();
int f = 1;
double x = 0;
while (ss < '0' || ss>'9') {
if (ss == '-') {
f = -1;
}
ss = getchar();
}
while (ss >= '0' && ss <= '9') {
x = x * 10 + ss - '0';
ss = getchar();
}
return x * f;
}
double a[20][20], c[20][20]; // c储存系数 b是每一个方程的值
int n;
double eps = 1e-7;
int main() {
n = read();
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]);
c[i][n+1] += a[i][j] * a[i][j] - a[i + 1][j] * a[i + 1][j];// 累加 平方
}
}
//高斯消元
for (int i = 1; i <= n; i++) {
int max = i;
for (int j = i+1; j <= n; j++) {
if (fabs(c[j][i]) > fabs(c[max][i])) max = j; //选最大的避免选到0
}
//因为这个一定有解所以没有判断是否有解的步骤
// 交换
for (int j = 1; j <= n+1; j++) {
swap(c[i][j], c[max][j]);
}
// c[i][n+1]是等式的值
//消元
for (int j = n+1; j >= 1; j--) {
c[i][j] = c[i][j] / c[i][i]; //对角线化1
}
for (int j = 1; j <= n; j++) {
if (j != i) {
double temp = c[j][i] / c[i][i]; // 乘以系第i列化为0
for (int k = 1; k <= n+1; k++) {
c[j][k] -= c[i][k] * temp;
}
}
}
}
for (int i = 1; i <= n; i++) {
printf("%0.3lf ",c[i][n+1]);
}
return 0;
}