高斯消元模板


高斯消元还是很好理解的,于是就找了个模板题做了下:Bzoj1013
不过好像用在那些dp题上面还是很不方便,感觉还是自己太菜了
这个题就很简单了,设出球心坐标 O(O1,O2...On) O ( O 1 , O 2 . . . O n )
写出距离方程式
ni=1(X0,iOi)2=ni=1(X1,iOi)2=...=ni=1(Xn,iOi)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
#include
#include
#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]);
}

你可能感兴趣的:(数学,----线性代数,OI)