BZOJ1013 高斯消元

题意:有一个球形空间产生器能够在n维空间中产生一个坚硬的球体。现在,你被困在了这个n维球体中,你只知道球面上n+1个点的坐标,你需要以最快的速度确定这个n维球体的球心坐标,以便于摧毁这个球形空间产生器。

 

设球心坐标为(x1,x2,x3....xn),可以对n + 1个点列出方程

∑(xi - ai)² = r²

将平方展开,变为Σxi² - 2 * ai * xi + ai² = r²,发现每个方程都有一个x1² + x2² + x3² + ......xn²,右边都有一个r²

那么将后n个方程全部对第一个方程作差,就可以消去xi²和r²,变成n个未知数和n个方程的线性方程组,用高斯消元解决就可以了

#include <map>
#include <set>
#include <ctime>
#include <cmath>
#include <queue>
#include <stack>
#include <vector>
#include <string>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <sstream>
#include <iostream>
#include <algorithm>
#include <functional>
using namespace std;
#define For(i, x, y) for(int i=x;i<=y;i++)  
#define _For(i, x, y) for(int i=x;i>=y;i--)
#define Mem(f, x) memset(f,x,sizeof(f))  
#define Sca(x) scanf("%d", &x)
#define Sca2(x,y) scanf("%d%d",&x,&y)
#define Sca3(x,y,z) scanf("%d%d%d",&x,&y,&z)
#define Scl(x) scanf("%lld",&x)  
#define Pri(x) printf("%d\n", x)
#define Prl(x) printf("%lld\n",x)  
#define CLR(u) for(int i=0;i<=N;i++)u[i].clear();
#define LL long long
#define ULL unsigned long long  
#define mp make_pair
#define PII pair<int,int>
#define PIL pair<int,long long>
#define PLL pair<long long,long long>
#define pb push_back
#define fi first
#define se second 
typedef vector<int> VI;
int read(){int x = 0,f = 1;char c = getchar();while (c<'0' || c>'9'){if (c == '-') f = -1;c = getchar();}
while (c >= '0'&&c <= '9'){x = x * 10 + c - '0';c = getchar();}return x*f;}
const double eps = 1e-9;
const int maxn = 15;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7; 
int N,M,K;
double MAP[maxn][maxn];
double base[maxn];
double ans[maxn];
void guess(){
    for(int i = 1; i <= N ; i ++){
        int r = i;
        for(int j = i + 1; j <= N ; j ++){
            if(fabs(MAP[r][i]) < fabs(MAP[j][i])) r = j;
        }
        if(fabs(MAP[r][i]) < eps){
            puts("No Solution");
            return;
        } 
        swap(MAP[i],MAP[r]);
        double div = MAP[i][i];
        for(int j = i;j <= N + 1; j ++) MAP[i][j] /= div;
        for(int j = i + 1; j <= N ; j ++){
            div = MAP[j][i];
            for(int k = i; k <= N + 1; k ++) MAP[j][k] -= MAP[i][k] * div;
        }
    }
    for(int i = N; i >= 1; i --){
        ans[i] = MAP[i][N + 1];
        for(int j = i + 1; j <= N ; j ++){
            ans[i] -= MAP[i][j] * ans[j];
        }
    }
    for(int i = 1; i <= N ; i ++) printf("%.3lf ",ans[i]);
}
int main(){
    Sca(N); double sum = 0;
     for(int i = 1; i <= N; i ++){
        scanf("%lf",&base[i]);
        sum += base[i] * base[i];    
    } 
    for(int i = 1; i <= N ; i ++){
        MAP[i][N + 1] = sum;;
        for(int j = 1; j <= N; j ++){
            double x; scanf("%lf",&x);
            MAP[i][j] = 2 * base[j] - 2 * x;
            MAP[i][N + 1] -= x * x;
        }
    }
    guess();
    return 0;
}

 

posted @ 2019-07-13 16:01  Hugh_Locke  阅读(237)  评论(0编辑  收藏  举报