题意:传送门
题解:首先可以列出每个点到圆心的方程,一下均以二维举例:
展开得到:
接着还是看不出啥,但是用1式减2式,用2式减3式得到:
之后使用高斯消元就得到了解,推广到n维也是这样做。
附上代码:
#include<bits/stdc++.h>
using namespace std;
const int maxn=15;
int n;
double s[maxn][maxn];
double a[maxn][maxn];
double ans[maxn];
void swap_r(int q,int p)
{
for(int i=1;i<=n+1;i++){
double t=a[p][i];
a[p][i]=a[q][i];
a[q][i]=t;
}
}
void swap_c(int q,int p)
{
for(int i=1;i<=n+1;i++){
double t=a[i][p];
a[i][p]=a[i][q];
a[i][q]=t;
}
}
void gs()
{
for(int i=1;i<n;i++){
double m=fabs(a[i][i]);
int p=i,q=i;
for(int j=i+1;j<=n;j++){
for(int k=i;k<=n;k++){
if(fabs(a[j][k])>m){
m=fabs(a[j][k]);
p=j;
q=k;
}
}
}
if(p!=i){
swap_r(p,i);
}
if(q!=i){
swap_c(q,i);
}
for(int j=i+1;j<=n;j++){
if(a[i][j]==0.0){
continue;
}
double t=a[j][i]/a[i][i];
a[j][i]=0.0;
for(int k=i+1;k<=n+1;k++){
a[j][k]-=t*a[i][k];
}
}
}
}
void red()
{
for(int i=n;i>1;i--){
for(int j=i-1;j>=1;j--){
if(a[j][i]==0){
continue;
}
double t=a[j][i]/a[i][i];
a[j][i]=0.0;
for(int k=i+1;k<=n+1;k++){
a[j][k]-=t*a[i][k];
}
}
}
}
void solve()
{
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
a[i][j]=2*(s[i+1][j]-s[i][j]);
}
}
for(int i=1;i<=n;i++){
for(int j=1;j<=n;j++){
a[i][n+1]+=s[i+1][j]*s[i+1][j]-s[i][j]*s[i][j];
}
}
for(int i=1;i<=n;i++){
a[n+1][i]=i;
}
gs();
red();
for(int i=1;i<=n;i++){
ans[(int)a[n+1][i]]=a[i][n+1]/a[i][i];
}
printf("%.3f",ans[1]);
for(int i=2;i<=n;i++){
printf(" %.3f",ans[i]);
}
printf("\n");
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n+1;i++){
for(int j=1;j<=n;j++){
scanf("%lf",&s[i][j]);
}
}
solve();
return 0;
}