bzoj 1013 [JSOI2008]球形空间产生器 - 高斯消元
1013: [JSOI2008]球形空间产生器sphere
Time Limit: 1 Sec Memory Limit: 162 MBDescription
有一个球形空间产生器能够在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
0.0 0.0
-1.0 1.0
1.0 0.0
Sample Output
0.500 1.500
HINT
提示:给出两个定义:1、 球心:到球面上任意一点距离都相等的点。2、 距离:设两个n为空间上的点A, B
的坐标为(a1, a2, …, an), (b1, b2, …, bn),则AB的距离定义为:dist = sqrt( (a1-b1)^2 + (a2-b2)^2 +
… + (an-bn)^2 )
设球心坐标为(x1, x2, .....xn)
球上点坐标为
(a1, a2, a3 ... an)
(b1, b2,b2 ... bn)
..
..
..
根据距离相同,可以列出方程
$(a1 - x1) ^ 2 + (a2 - x2) ^ 2 + ... (an - xn) ^ 2 = (b1 - x1) ^ 2 + (b2 - x2) ^ 2 + ... (bn - xn) ^ 2$
即$\sum{2 * (bi - ai) xi} = \sum{bi ^ 2 - ai ^ 2}$
高斯消元就好了
1 #include <iostream> 2 #include <algorithm> 3 #include <cstdio> 4 #include <cstring> 5 #define LL long long 6 7 using namespace std; 8 9 int n; 10 double a[20][20]; 11 double b[20][20]; 12 double x[20]; 13 14 inline LL read() 15 { 16 LL x = 0, w = 1; char ch = 0; 17 while(ch < '0' || ch > '9') { 18 if(ch == '-') { 19 w = -1; 20 } 21 ch = getchar(); 22 } 23 while(ch >= '0' && ch <= '9') { 24 x = x * 10 + ch - '0'; 25 ch = getchar(); 26 } 27 return x * w; 28 } 29 30 void DFS(int k) 31 { 32 if(k == n) { 33 x[n] = b[n][n + 1] / b[n][n]; 34 return; 35 } 36 for(int i = k + 1; i <= n; i++) { 37 double t = b[k][k] / b[i][k]; 38 for(int j = k + 1; j <= n + 1; j++) { 39 b[i][j] = b[k][j] - b[i][j] * t; 40 } 41 } 42 DFS(k + 1); 43 for(int i = n; i > k; i--) { 44 b[k][n + 1] -= b[k][i] * x[i]; 45 } 46 x[k] = b[k][n + 1] / b[k][k]; 47 } 48 49 int main() 50 { 51 n = read(); 52 for(int i = 1; i <= n + 1; i++) { 53 for(int j = 1; j <= n; j++) { 54 scanf("%lf", &a[i][j]); 55 } 56 } 57 for(int i = 1; i <= n; i++) { 58 for(int j = 1; j <= n; j++) { 59 b[i][j] = 2 * (a[i + 1][j] - a[i][j]); 60 b[i][n + 1] += a[i + 1][j] * a[i + 1][j] - a[i][j] * a[i][j]; 61 } 62 } 63 DFS(1); 64 for(int i = 1; i < n; i++) { 65 printf("%.3lf ", x[i]); 66 } 67 printf("%.3lf", x[n]); 68 return 0; 69 }