n+1个坐标可以列出n个方程,以二维为例,设圆心为(x,y),给出三个点分别是(a1,b1),(a2,b2),(a3,b3)
因为圆上各点到圆心的距离相同,于是可以列出距离方程\[ (a1-x)^2+(b1-y)^2=(a2-x)^2+(b2-y)^2 \]\[ (a1-x)^2+(b1-y)^2=(a3-x)^2+(b3-y)^2 \] 然后化简\[ -2(a2-a1)x-2(b2-b1)y=a1^2-a2^2+b1^2-b2^2 \]\[ -2(a3-a1)x-2(b3-b1)y=a1^2-a3^2+b1^2-b3^2; \] 然后就可以用高斯消元了#include#include using namespace std;const int N=25;int n;double f[N],a[N][N],p;void gaosi(){ for(int i=1;i<=n;i++) { int nw=i; for(int j=i+1;j<=n;j++) if(a[j][i]>a[nw][i]) nw=j; for(int j=i;j<=n+1;j++) swap(a[nw][j],a[i][j]); for(int j=i+1;j<=n+1;j++) a[i][j]/=a[i][i]; a[i][i]=1; for(int j=i+1;j<=n;j++) { for(int k=i+1;k<=n+1;k++) a[j][k]-=a[j][i]*a[i][k]; a[j][i]=0; } } for(int i=n;i>=1;i--) for(int j=i+1;j<=n;j++) { a[i][n+1]-=a[i][j]*a[j][n+1]; a[i][j]=0; }}int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) scanf("%lf",&f[i]); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { scanf("%lf",&p); a[i][j]=2*(p-f[j]); a[i][n+1]+=p*p-f[j]*f[j]; } gaosi(); for(int i=1;i<=n;i++) printf("%.3lf ",a[i][n+1]); return 0;}