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

[文章目录]

Description

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

高斯消元裸题。将每个a1x1+a2x2+....anxn=ansn看成一个n+1项的向量。然后罗列起来,构成一个n*n+1的矩阵。然后通过向量相减,使得n*n的子矩阵变成单位矩阵,就是方程的解。具体做法:将1~n行找出一个xi,将其变为1,然后每个向量的第i位都通过该向量消为0。大模拟啊。

#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n;
double map[20][20],ans[20],in[20];
void SW(int x,int y)
{
	for(int i=1;i<=n;i++)
		swap(map[x][i],map[y][i]);
	swap(ans[x],ans[y]);
}
int main()
{
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%lf",&in[i]);
	double x;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=n;j++)
		{
			scanf("%lf",&x);
			map[i][j]=2*x-2*in[j];
			ans[i]+=(x*x-in[j]*in[j]);
			in[j]=x;
		}
	for(int i=1;i<=n;i++)
	{
		double tmp=0;int k=1;
		for(int j=i;j<=n;j++)
			if(fabs(map[j][i])>tmp) tmp=map[j][i],k=j;
		SW(k,i); ans[i]/=map[i][i];
		for(int j=n;j>=i;j--) map[i][j]/=map[i][i];
		for(int j=1;j<=n;j++)
			if(j!=i)
			{
				double pl=map[j][i];
				for(int ii=i;ii<=n;ii++)
					map[j][ii]-=pl*map[i][ii];
				ans[j]-=pl*ans[i];
			}
	}
	printf("%.3lf",ans[1]);
	for(int i=2;i<=n;i++) printf(" %.3lf",ans[i]);
	return 0;
}

 

发表评论

邮箱地址不会被公开。 必填项已用*标注