[BZOJ1013][JSOI2008]球形空间产生器sphere

[BZOJ1013][JSOI2008]球形空间产生器sphere

试题描述

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

输入

第一行是一个整数n(1<=N=10)。接下来的n+1行,每行有n个实数,表示球面上一点的n维坐标。每一个实数精确到小数点
后6位,且其绝对值都不超过20000。

输出

有且只有一行,依次给出球心的n维坐标(n个实数),两个实数之间用一个空格隔开。每个实数精确到小数点
后3位。数据保证有解。你的答案必须和标准输出一模一样才能够得分。

输入示例

2
0.0 0.0
-1.0 1.0
1.0 0.0

输出示例

0.500 1.500

数据规模及约定

见“输入

题解

因为是个球,所以第 i 号点和第 i+1 号点到球心的距离相等(1 ≤ i ≤ n),推一波式子发现未知数平方项被消了,所以就是个裸的高斯消元。

#include <iostream>
#include <cstdio>
#include <cstring>
#include <cctype>
#include <algorithm>
#include <cmath>
using namespace std;

int read() {
	int x = 0, f = 1; char c = getchar();
	while(!isdigit(c)){ if(c == '-') f = -1; c = getchar(); }
	while(isdigit(c)){ x = x * 10 + c - '0'; c = getchar(); }
	return x * f;
}

#define maxn 20
#define eps 1e-6
int n;
double x[maxn][maxn], A[maxn][maxn];

double sqr(double x) { return x * x; }

int main() {
	n = read();
	for(int i = 1; i <= n + 1; i++)
		for(int j = 1; j <= n; j++)
			scanf("%lf", &x[i][j]);
	
	for(int i = 1; i <= n; i++)
		for(int j = 1; j <= n; j++)
			A[i][j] = 2.0 * (x[i][j] - x[i+1][j]), A[i][n+1] += sqr(x[i][j]) - sqr(x[i+1][j]);
	/*for(int i = 1; i <= n; i++) {
		for(int j = 1; j <= n; j++) printf("%.3lf ", A[i][j]);
		printf("| %.3lf\n", A[i][n+1]);
	}*/
	for(int i = 1; i <= n; i++) {
		int x; bool has = 0;
		for(x = i; x <= n; x++) if(fabs(A[x][i]) > eps) {
			has = 1; break;
		}
		if(!has) continue;
		if(x != i) for(int j = 1; j <= n + 1; j++) swap(A[x][j], A[i][j]);
		double t = A[i][i];
		for(x = 1; x <= n; x++) if(x != i && fabs(A[x][i]) > eps) {
			double r = -t / A[x][i];
			for(int j = 1; j <= n + 1; j++) A[x][j] = A[x][j] * r + A[i][j];
		}
	}
	/*for(int i = 1; i <= n; i++) {
		for(int j = 1; j <= n; j++) printf("%.3lf ", A[i][j]);
		printf("| %.3lf\n", A[i][n+1]);
	}*/
	
	for(int i = 1; i < n; i++) printf("%.3lf ", A[i][n+1] / A[i][i]);
	printf("%.3lf\n", A[n][n+1] / A[n][n]);
	
	return 0;
}

 

posted @ 2016-09-24 22:24  xjr01  阅读(305)  评论(0编辑  收藏  举报