342 字
2 分钟
BZOJ 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
2
0.0 0.0
-1.0 1.0
1.0 0.0
Sample Output
0.500 1.500
题解
直接列方程 到每个点距离相等
手动化简一下 就出来了
BZOJ 竟然不能多输出一个空格(气)
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>using namespace std;double c[20],a[15][15],b[15],x[15],d;int n;void gauss(){ int im,num=1; for(int k=1;k<=n;k++,num++){ im=k; for(int i=k+1;i<=n;i++) if(fabs(a[i][k])>fabs(a[im][k])) im=i; if(im!=k){ for(int i=k;i<=n;i++) swap(a[num][i],a[im][i]); swap(b[num],b[im]); } if(!a[num][k]){num--;continue;} for(int i=num+1;i<=n;i++){ if(!a[num][k])continue; double t=a[i][k]/a[num][k]; for(int j=k;j<=n+1;j++){ a[i][j]-=t*a[k][j]; } b[i]-=t*b[k]; } } for(int i=n;i>=1;i--){ for(int j=n;j>=i+1;j--) b[i]-=a[i][j]*x[j]; x[i]=b[i]/a[i][i]; }}int main(){ scanf("%d",&n); for(int i=1;i<=n;i++)scanf("%lf",&c[i]); for(int i=1;i<=n;i++){ for(int j=1;j<=n;j++){ scanf("%lf",&d); a[i][j]=d-c[j]; b[i]+=d*d-c[j]*c[j]; } b[i]/=2; } gauss(); for(int i=1;i<n;i++){ printf("%.3lf ",x[i]); } printf("%.3lf",x[n]);}
BZOJ 1013 [JSOI2008]球形空间产生器sphere 高斯消元
https://www.nekomio.com/posts/18/