作者:岸芷汀兰
一、题目:
二、思路:
高斯消元。
求出一个点
(x1,x2,…,xn)
(
x
1
,
x
2
,
…
,
x
n
)
,使得:
∑j=0n(ai,j−xj)2=C
∑
j
=
0
n
(
a
i
,
j
−
x
j
)
2
=
C
把方程转化一下,变量放在左边,常数放在右边,然后高斯消元就可以了。
技巧: 位运算。
三、代码:
#include<iostream>
#include<cstdio>
#include<cmath>
using namespace std;
inline int read(void) {
int x = 0, f = 1; char ch = getchar();
while (ch<'0' || ch>'9') {
if (ch == '-')f = -1;
ch = getchar();
}
while (ch >= '0'&&ch <= '9') {
x = x * 10 + ch - '0';
ch = getchar();
}
return f * x;
}
double a[20][20], b[20]/*增广矩阵最后一列*/, c[20][20]/*增广矩阵的前n列*/;
int n;
int main()
{
n = read();
for (register int i = 1; i <= n + 1; i++) {
for (register int j = 1; j <= n; j++) {
scanf_s("%lf", &a[i][j]);
}
}
for (register int i = 1; i <= n; i++) {
for (register 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];
}
}
for (register int i = 1; i <= n; i++) {
for (register int j = i; j <= n; j++) {
if (fabs(c[j][i]) > 1e-8) {
for (register int k = 1; k <= n; k++)swap(c[i][k], c[j][k]);
swap(b[i], b[j]);
}
}
for (register int j = 1; j <= n; j++) {
if (i == j)continue;
double rate = c[j][i] / c[i][i];
for (register int k = i; k <= n; k++)c[j][k] -= c[i][k] * rate;
b[j] -= b[i] * rate;
}
}
for (register int i = 1; i < n; i++)printf("%.3lf ", b[i] / c[i][i]);
printf("%.3lf", b[n] / c[n][n]);
return 0;
}