高斯消元——球形空间产生器sphere

来源:互联网 发布:linux awk 分隔符 编辑:程序博客网 时间:2024/06/05 11:20

题目来源

BZOJ[JSOI2008]球形空间产生器sphere

http://www.lydsy.com/JudgeOnline/problem.php?id=1013


思路

设球心在第i维的坐标为ans[1~n]

由于是球体 所以所有点到球心的距离都相等

所以两点可联立一个关于ans[1~n]的方程

再用高斯消元求解即为球心坐标


代码(C++)

#include <cmath>#include <cstdio>#include <algorithm>using namespace std;int n,maxn; double p[15][15],ans[15],a[15][15],maxx,t;int main(){    scanf("%d",&n);    for(int i=1;i<=n+1;++i)        for(int j=1;j<=n;++j)            scanf("%lf",&p[i][j]);    for(int i=1;i<=n;++i)        for(int j=1;j<=n;++j)            a[i][j]=2.000*(p[i][j]-p[i+1][j]),a[i][n+1]+=1.000*p[i][j]*p[i][j]-p[i+1][j]*p[i+1][j];    for(int i=1;i<=n;++i)    {        maxx=a[i][i]; maxn=i;        for(int j=i+1;j<=n;++j)            if(abs(a[j][i])>maxx)                maxx=abs(a[j][i]),maxn=j;        for(int k=1;k<=n+1;++k)            swap(a[i][k],a[maxn][k]);        for(int j=i+1;j<=n;++j)        {            t=a[j][i]/a[i][i];            for(int k=i;k<=n+1;++k)                a[j][k]-=t*a[i][k];        }    }    for(int i=n;i>=1;--i)    {        ans[i]=a[i][n+1]/a[i][i];        for(int j=i-1;j>=1;--j)            a[j][n+1]-=a[j][i]*ans[i];    }    for(int i=1;i<n;++i)        printf("%.3lf ",ans[i]);    printf("%.3lf",ans[n]);    return 0;}