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

本文讨论了利用高斯消元法解决n维空间上的球形方程组的问题,通过将多个方程组转化为一维方程组来简化计算过程,并详细介绍了具体的实现步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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

/*

* 分析:
* 裸的高斯消元题
* 二维平面上的圆上的点与圆心的距离有(x-a)^2+(y-b)^2 = r^2
* 三维空间上的球上的点与球心的距离有(x-a)^2+(y-b)^2+(z-c)^2 = r^2
* 同理:在n维空间上的球上的点与球心的距离有sigma((xi-ai)^2) = r^2,圆心为(a1,a2,...,an)
*
* 另外,在二维平面上,可由三点(不共线)确定一个园,在三维上四点(不共线)确定一个球,
* 同理,在n维平面上,可由n+1个点(不共线)确定一个n维的球。
*
* 这样,题目就可以转化为n+1个方程组,但是是平方级别的,如何转化为一维的?
* 我们不妨对于相邻的两个方程组左右分别相减,可以发现:
* 2*(x21 - x11)*x1 + 2*(x22 - x12)*x2 +...+2*(x2n - x1n) = (x21^2 - x11^1)+...+(x2n^2 - x1n^2)
* 这样,由n+1个方程组就可以转化为了n个一维的方程组了。下面,直接用高斯消元法即可解决该问题
*
* */

#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>

using namespace std;

const int X = 20;
#define esp 1e-8

double dp[X][X];
double a[X][X],b[X][X];
double f[X];
int n;

double gauss(){
	for(int i=1;i<=n;i++){
		int x = i;
		for(int j=i+1;j<=n;j++)
			if(fabs(a[j][i]-a[x][i])>esp)
				x = j;
		if(x!=i)
			for(int j=1;j<=n+1;j++)
				swap(a[i][j],a[x][j]);
		for(int j=i+1;j<=n;j++)
			if(fabs(a[j][i])>esp){
				double temp = a[j][i] / a[i][i];
				for(int k=i;k<=n+1;k++)
					a[j][k] -= temp*a[i][k];
			}
	}
	for(int i=n;i;i--){
		double temp = a[i][n+1];
		for(int j=i+1;j<=n;j++)
			temp -= f[j]*a[i][j];
		f[i] = temp / a[i][i];
	}
}

int main(){
	cin>>n;
	for(int i=1;i<n+2;i++)
		for(int j=1;j<=n;j++)
			scanf("%lf",&b[i][j]);
	for(int i=1;i<=n;i++){
		double temp = 0;
		for(int j=1;j<=n;j++){
			temp += b[i+1][j]*b[i+1][j]-b[i][j]*b[i][j];
			a[i][j] = 2*(b[i+1][j]-b[i][j]);
		}
		a[i][n+1] = temp;
	}
	gauss();
	for(int i=1;i<n;i++)
		printf("%.3lf ",f[i]);
	printf("%.3lf\n",f[n]);
	return 0;
}

  

转载于:https://www.cnblogs.com/yejinru/archive/2012/12/20/2825814.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值