您的位置:首页 > Web前端 > JavaScript

bzoj1013 [JSOI2008] 球形空间产生器sphere 高斯消元

2018-01-16 09:27 337 查看

Description

  有一个球形空间产生器能够在n维空间中产生一个坚硬的球体。现在,你被困在了这个n维球体中,你只知道球

面上n+1个点的坐标,你需要以最快的速度确定这个n维球体的球心坐标,以便于摧毁这个球形空间产生器。

数据保证有解

Solution

据说有个套路就是看到n很小要先想高斯消元和状压dp网络流迭代加深

我们可以设坐标列方程,设球的半径为d,那么对于第一个点有d2=∑i=1n(xi−ai,1)2其中a为给出的球上坐标,剩下的点同理

不难发现这样联立然后相邻的两个式子可以消去平方项,高斯消元求解就行辣

Code

#include <stdio.h>
#include <string.h>
#include <algorithm>
using std:: swap;
#define rep(i,st,ed) for (int i=st;i<=ed;++i)
#define fill(x,t) memset(x,t,sizeof(x))
double a[21][21],b[21][21];
void gauss(int n,int m) {
rep(i,1,n) {
int rec=i;
rep(j,i+1,n) if (a[j][i]>a[rec][i]) rec=j;
if (rec!=i) rep(j,1,m) swap(a[i][j],a[rec][j]);
double t=a[i][i];
rep(j,1,m) a[i][j]/=t;
rep(j,1,n) if (i!=j&&a[j][i]) {
t=a[j][i];
rep(k,1,m) a[j][k]-=a[i][k]*t;
}
}
rep(i,1,n-1) printf("%.3lf ", a[i][m]);
printf("%.3lf\n", a
[m]);
}
int main(void) {
int n; scanf("%d",&n);
rep(i,1,n+1) rep(j,1,n) scanf("%lf",&b[i][j]);
// rep(i,1,n) b[n+1][i]=b[1][i];
rep(i,1,n) rep(j,1,n) {
a[i][j]=2*(b[i][j]-b[i+1][j]);
a[i][n+1]+=b[i][j]*b[i][j]-b[i+1][j]*b[i+1][j];
}
gauss(n,n+1);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: