【高斯消元】洛谷P4035 [JSOI2008]球形空间产生器

版权声明:转载无所谓的。。。 https://blog.csdn.net/xuxiayang/article/details/82663533

链接

https://www.luogu.org/problemnew/show/P4035


大意

给定一个在 n 维意义下的球面上的 n + 1 个点,求出球心的坐标


思路

因为这 n + 1 个点到球形的距离相同,所以可以列出一个方程

j = 0 n ( a i , j x j ) 2 =

然后因为这个方程是一个 n 元二次方程,我们把相邻两个方程做差,就得到了一个 n 元一次方程

j = 1 n ( a i , j 2 a i + 1 , j 2 2 x j ( a i , j a i + 1 , j ) ) = 0

这时我们通过移项,把变量放在左边,常数放在右边

j = 1 n 2 x j ( a i , j a i + 1 , j ) = j = 1 n ( a i , j 2 a i + 1 , j 2 )

此时右边可以通过预处理求出,这时跑高斯消元即可


高斯消元步骤

  1. 找到 x [ i ] 的系数不为0的一个方程
  2. 将系数不为0的方程优先放到前面
  3. 加减消元

代码

#include<cstdio>
#include<cmath>
#define r(i,a,b) for(register int i=a;i<=b;i++)
using namespace std;int n;
double a[20][20],b[20],c[20][20];
inline double power(register double x){return x*x;}
inline void swap(register double &x,register double &y){double t=x;x=y;y=t;return;}
signed main()
{
    scanf("%d",&n);
    r(i,1,n+1) r(j,1,n) scanf("%lf",&a[i][j]);
    r(i,1,n) r(j,1,n) c[i][j]=(a[i][j]-a[i+1][j])*2,b[i]+=power(a[i][j])-power(a[i+1][j]);//c表示系数,b表示常数
    r(i,1,n) 
    {
        r(j,i+1,n) 
        if(fabs(c[j][i]>1e-8)) //找到系数不为0的矩阵
        {
            r(k,1,n) swap(c[i][k],c[j][k]);
            swap(b[i],b[j]);
        }
        r(j,1,n)
        {
            if(i==j) continue;
            double rnt=c[j][i]/c[i][i];
            r(k,i,n) c[j][k]-=c[i][k]*rnt;//高斯消元
            b[j]-=b[i]*rnt;
        }
    }
    r(i,1,n) printf("%.3lf ",b[i]/c[i][i]);//输出解
}

猜你喜欢

转载自blog.csdn.net/xuxiayang/article/details/82663533