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; }