高斯消元还是很好理解的,于是就找了个模板题做了下:Bzoj1013
不过好像用在那些dp题上面还是很不方便,感觉还是自己太菜了
这个题就很简单了,设出球心坐标
O(O1,O2...On)
O
(
O
1
,
O
2
.
.
.
O
n
)
写出距离方程式
∑ni=1(X0,i−Oi)2=∑ni=1(X1,i−Oi)2=...=∑ni=1(Xn,i−Oi)2
∑
i
=
1
n
(
X
0
,
i
−
O
i
)
2
=
∑
i
=
1
n
(
X
1
,
i
−
O
i
)
2
=
.
.
.
=
∑
i
=
1
n
(
X
n
,
i
−
O
i
)
2
两边展开就得到了n个线性方程组,消元即可
偷懒用了向量,其实应该学一学stl的valarray的
#include<stdio.h>
#include<string.h>
#include<algorithm>
#define db double
using namespace std;
int n; db x[20][20],k[20],A[20];
struct vec{
db v[20];
inline db& operator[] (int j){ return v[j]; }
inline vec operator- (vec b){
vec c;
for(int i=0;i<20;++i) c[i]=v[i]-b[i];
return c;
}
inline vec operator* (db j){
vec c;
for(int i=0;i<20;++i) c[i]=v[i]*j;
return c;
}
} s[20];
int main(){
scanf("%d",&n);
for(int i=0;i<=n;++i)
for(int j=1;j<=n;++j) scanf("%lf",x[i]+j);
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
s[i][j]=2*(x[i][j]-x[0][j]);
k[i]+=-x[0][j]*x[0][j]+x[i][j]*x[i][j];
}
}
for(int i=1;i<=n;++i){
for(int j=i;j<=n;++j) if(s[j][i]){ swap(s[j],s[i]); break; }
for(int j=i+1;j<=n;++j){
k[j]-=k[i]*(s[j][i]/s[i][i]);
s[j]=s[j]-s[i]*(s[j][i]/s[i][i]);
}
}
for(int i=n;i;--i){
for(int j=n;j>i;--j) k[i]-=A[j]*s[i][j];
A[i]=k[i]/s[i][i];
}
for(int i=1;i<=n;++i) printf("%.3lf ",A[i]);
}