bzoj 1013

高斯消元裸题

设给出的每一组坐标为$(a_i1,a_i2,...,a_in)(i\in[1,n+1])$,设球心坐标为$(x_1,x_2,...,x_n)$

设每个点到球心的距离为$d_i$

那么一定有方程:

$d_1==d_2$

$d_2==d_3$

...

$d_n==d_n+1$

展开之后,就是:

$\sum_{i=1}^{n}(a_{1i}-x_{i})^2==\sum_{i=1}^{n}(a_{2i}-x_{i})^2$

...

$\sum_{i=1}^{n}(a_{ni}-x_{i})^2==\sum_{i=1}^{n}(a_{(n+1)i}-x_{i})^2$

不要担心平方项,因为他们要么可以约掉要么是常值

所以整理之后就是这样:

$\sum_{i=1}^{n}2*(a_{2i}-a_{1i})*x_i==\sum_{i=1}^{n}(a_{2i}^2-a_{1i}^2)$

...

$\sum_{i=1}^{n}2*(a_{(n+1)i}-a_{ni})*x_i==\sum_{i=1}^{n}(a_{(n+1)i}^2-a_{1i}^2)$

那么就是高斯消元裸题了嘛

#include <cstdio>
#include <cmath>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
using namespace std;
const double eps=0.000001;
double a[15][15];
double x[15][15];
int n;
void Gauss()
{
    for(int i=1;i<=n;i++)
    {
        int temp=i;
        while(fabs(a[temp][i])<=eps)temp++;
        if(temp!=i)for(int j=i;j<=n+1;j++)swap(a[temp][j],a[i][j]);
        double now=a[i][i];
        for(int j=i;j<=n+1;j++)a[i][j]/=now;
        for(int j=i+1;j<=n;j++)
        {
            now=a[j][i];
            for(int k=i;k<=n+1;k++)a[j][k]-=now*a[i][k];
        }
    }
    for(int i=n;i>=1;i--)
    {
        for(int j=i-1;j>=1;j--)a[j][n+1]-=a[i][n+1]*a[j][i];
    }
}
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n+1;i++)
    {
        for(int j=1;j<=n;j++)scanf("%lf",&x[i][j]);
        if(i!=1)for(int j=1;j<=n;j++)a[i-1][j]=2.0*(x[i][j]-x[i-1][j]),a[i-1][n+1]+=x[i][j]*x[i][j]-x[i-1][j]*x[i-1][j];
    }
    Gauss();
    for(int i=1;i<=n;i++)printf("%.3lf ",a[i][n+1]);
    printf("\n");
    return 0;
}

 

posted @ 2019-05-05 18:13  lleozhang  Views(120)  Comments(0Edit  收藏  举报
levels of contents