Steven_MengのBlog

假设我们设答案坐标$(x_1,x_2, \cdots ,x_n)$,对于两个点$(a_1,a_2, \cdots ,a_n),(b_1,b_2, \cdots ,b_n)$显然有$\sqrt {(a_1 -x_1)^2 + (a_2-x_2)^2+ \cdots (a_n - x_n)^2} = \sqrt {(b_1 -x_1)^2 + (b_2-x_2)^2+ \cdots (b_n - x_n)^2}$

即$\sum a_i^2 + \sum 2a_i \times x_i+\sum x_i^2 = \sum b_i^2 + \sum 2b_i \times x_i+\sum x_i^2$

即$\sum x_i \times 2(a_i-b_i)=\sum a_i^2-\sum b_i^2$。

对相邻的两个点列出如此的方程共有$n$个,可知一定有解。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
#include <bits/stdc++.h>
#define MAXN 105
using namespace std;
inline int read(){
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<<1)+(x<<3)+(ch^'0');
ch=getchar();
}
return x*f;
}
namespace Gauss{
double c[MAXN][MAXN],ans[MAXN];
inline void gauss(int n){
for (register int i=1;i<=n;++i){
int id=i;
for (register int j=i+1;j<=n;++j){
if (fabs(c[j][i])>fabs(c[id][i])) id=j;
}
if (id!=i) for (register int j=i;j<=n+1;++j) swap(c[i][j],c[id][j]);
for (register int j=i+1;j<=n;++j){
double rate=c[j][i]/c[i][i];
for (register int k=i;k<=n+1;++k) c[j][k]-=c[i][k]*rate;
}
}
for (register int i=n;i>=1;--i){
for (register int j=i+1;j<=n;++j){
c[i][n+1]-=c[j][n+1]*c[i][j];
}
c[i][n+1]/=c[i][i];
}
}
}
using namespace Gauss;
double a[MAXN][MAXN];
int n;
int main(){
n=read();
for (register int i=1;i<=n+1;++i){
for (register int j=1;j<=n;++j){
scanf("%lf",&a[i][j]);
}
}
for (register int i=1;i<=n;++i){
for (register int j=1;j<=n;++j) {
c[i][j]=2.00*(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];
}
}
gauss(n);
for (register int i=1;i<=n;++i){
printf("%.3lf ",c[i][n+1]);
}
}

 评论