题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1013
根据距离式子,两个点的话,两边平方再消掉x^2之后有:
a1^2 - 2*a1*x1 + a2^2 - 2*a2*x2 + ... + an^2 - 2*an*xn = b1^2 - 2*b1*x1 + b2^2 - 2*b2*x2 + ... +bn^2 - 2*bn*xn
把x放到一边,有:
2 ( b1 - a1 ) * x1 + 2 ( b2 - a2 ) * x2 + ... + 2 ( bn - an ) *xn = b1^2 - a1^2 + b2^2 - a2^2 + ... + bn^2 - an^2
所以后n个点全和第一个点作差,就得到了n个式子。
这是没管无解、多解的高斯消元。把该未知数的系数弄成1,就能方便地输出n+1位置的值作为答案了。
注意改的过程中 一些参数可能会被改!所以注意顺序或者建一个tmp存一下!
#include<iostream> #include<cstdio> #include<cstring> using namespace std; const int N=15; int n; double a[N][N+1]; void read() { scanf("%d",&n);double tp; for(int i=1;i<=n;i++)scanf("%lf",&a[0][i]); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) { scanf("%lf",&tp); a[i][j]=2*(tp-a[0][j]); a[i][n+1]+=tp*tp-a[0][j]*a[0][j]; } } void gauss() { for(int i=1,now=1;i<=n;i++,now++) { int k=now; //不要k=n+1然后j从now开始,可能系数全负 for(int j=now+1;j<=n;j++)if(a[j][i]>a[k][i])k=j; for(int j=1;j<=n+1;j++)swap(a[k][j],a[now][j]); for(int j=n+1;j>=i;j--) //不然a[now][i]的值会改!!! a[now][j]/=a[now][i]; for(int j=1;j<=n;j++) //1~n if(j!=now) // for(int l=n+1;l>=i;l--)//////同上,正序 a[j][i]的值会改!!! a[j][l]-=a[j][i]*a[now][l]; } } int main() { read(); gauss(); for(int i=1;i<n;i++)printf("%.3lf ",a[i][n+1]); printf("%.3lf",a[n][n+1]); return 0; }