本文主要是介绍1013: [JSOI2008]球形空间产生器sphere(高斯消元),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
Description
有一个球形空间产生器能够在n维空间中产生一个坚硬的球体。现在,你被困在了这个n维球体中,你只知道球
面上n+1个点的坐标,你需要以最快的速度确定这个n维球体的球心坐标,以便于摧毁这个球形空间产生器。
Input
第一行是一个整数n(1<=N=10)。接下来的n+1行,每行有n个实数,表示球面上一点的n维坐标。每一个实数精确到小数点
后6位,且其绝对值都不超过20000。
Output
有且只有一行,依次给出球心的n维坐标(n个实数),两个实数之间用一个空格隔开。每个实数精确到小数点
后3位。数据保证有解。你的答案必须和标准输出一模一样才能够得分。
Sample Input
0.0 0.0
-1.0 1.0
1.0 0.0
Sample Output
HINT
提示:给出两个定义:1、 球心:到球面上任意一点距离都相等的点。2、 距离:设两个n为空间上的点A, B
的坐标为(a1, a2, …, an), (b1, b2, …, bn),则AB的距离定义为:dist = sqrt( (a1-b1)^2 + (a2-b2)^2 +
… + (an-bn)^2 )
因为球上的点到球心的距离都是一样的,我们可以利用第一个点到球心的距离等于第二点到球心的距离列一个方程,第一个点到球心的距离和第三个点到球心的距离列第二个方程,因为给了n+1个点,所以可以列出n个方程,然后用高斯消元就可以解得n个未知数就是球心的坐标了。
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define LL long longusing namespace std;const double eps = 1e-8;double a[15][15],x[15];//方程的左边的矩阵和等式右边的值,求解之后x存的就是结果
int equ,var;//方程数和未知数个数int Gauss()
{int i,j,k,col,max_r;for(k=0,col=0;k<equ&&col<var;k++,col++){max_r=k;for(i=k+1;i<equ;i++)if(fabs(a[i][col])>fabs(a[max_r][col]))max_r=i;if(fabs(a[max_r][col])<eps)return 0;if(k!=max_r){for(j=col;j<var;j++)swap(a[k][j],a[max_r][j]);swap(x[k],x[max_r]);}x[k]/=a[k][col];for(j=col+1;j<var;j++)a[k][j]/=a[k][col];a[k][col]=1;for(i=0;i<equ;i++)if(i!=k){x[i]-=x[k]*a[i][k];for(j=col+1;j<var;j++)a[i][j]-=a[k][j]*a[i][col];a[i][col]=0;}}return 1;
}double f[15];int main(void)
{int n,i,j;while(scanf("%d",&n)==1){for(i=0;i<n;i++)scanf("%lf",&f[i]);for(i=0;i<n;i++){for(j=0;j<n;j++){double t;scanf("%lf",&t);a[i][j] = 2*(t-f[j]);x[i] += t*t - f[j]*f[j];}}equ = var = n;Gauss();for(i=0;i<n-1;i++)printf("%.3f ",x[i]);printf("%.3f\n",x[i]);}return 0;
}
这篇关于1013: [JSOI2008]球形空间产生器sphere(高斯消元)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!