[bzoj1013](JSOI2008)球形空间产生器sphere(高斯消元)
2015-03-26 18:09
453 查看
Description
有一个球形空间产生器能够在n维空间中产生一个坚硬的球体。现在,你被困在了这个n维球体中,你只知道球面上n+1个点的坐标,你需要以最快的速度确定这个n维球体的球心坐标,以便于摧毁这个球形空间产生器。Input
第一行是一个整数,n。接下来的n+1行,每行有n个实数,表示球面上一点的n维坐标。每一个实数精确到小数点后6位,且其绝对值都不超过20000。Output
有且只有一行,依次给出球心的n维坐标(n个实数),两个实数之间用一个空格隔开。每个实数精确到小数点后3位。数据保证有解。你的答案必须和标准输出一模一样才能够得分。Sample Input
20.0 0.0
-1.0 1.0
1.0 0.0
Sample Output
0.500 1.500HINT
数据规模:对于40%的数据,1<=n<=3
对于100%的数据,1<=n<=10
提示:给出两个定义:
1、 球心:到球面上任意一点距离都相等的点。
2、 距离:设两个n为空间上的点A, B的坐标为$(a_1, a_2, …, a_n), (b_1, b_2, …, b_n)$,则AB的距离定义为:$$dist = \sqrt{ (a_1-b_1)^2 + (a_2-b_2)^2 + … + (a_n-b_n)^2 }$$
分析
设球心坐标为$(x_1, x_2, ... , x_n)$,根据定义可以列出方程组:$$ \forall i,j \in [1,n+1]: \sum_{k=1}^N (x_k - a_{ik})^2 = \sum_{k=1}^N (x_k - a_{jk})^2$$.
展开后移项相减,得到
$$\sum_{k=1}^N 2(a_{ik} - a_{jk})x_k = a_{ik}^2 - a_{jk}^2 $$
由于变量有N个,我们只需选取其中N组线性无关(或可以使所有无向边(i,j)构成一棵树)的(i,j)方程来求解即可。
题目本身不难,可是为学校OJ造测试数据这种事简直醉人……我的做法是先随机出一个N维向量作为答案,再随机出半径R,接着循环N+1次,每次随机一个N-1维向量,求出这条直线与球的交点……最终还要运行一遍本题的高斯消元判断这些点是否线性相关……
好吧其实真正的问题是我太水了……敲错了datamaker调试了好久= =
1 /**************************************************************
2 Problem: 1013
3 User: AsmDef
4 Language: C++
5 Result: Accepted
6 Time:0 ms
7 Memory:1272 kb
8 ****************************************************************/
9
//Asm_Def
#include <iostream>
#include <cctype>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <cmath>
#include <queue>
using namespace std;
template<typename T>inline void getd(T &x){
char c = getchar();
bool minus = 0;
while(!isdigit(c) && c != '-')c = getchar();
if(c == '-')minus = 1, c = getchar();
x = c - '0';
while(isdigit(c = getchar()))x = x * 10 + c - '0';
if(minus)x = -x;
}
/*======================================================*/
const double eps = 1e-12;
double *Eq[11], Ans[11];
int N;
inline void init(){
double a, P[11][12];
getd(N);int i, j;
for(j = 0;j < N;++j)scanf("%lf", *P + j);
for(i = 1;i <= N;++i){
for(j = 0;j < N;++j)
scanf("%lf", P[i] + j);
P[i-1]
= 0;
for(j = 0;j < N;++j){
a = P[i-1][j] + P[i][j];
P[i-1][j] = P[i][j] - P[i-1][j];
P[i-1]
+= a * P[i-1][j] / 2.0;
}
Eq[i-1] = P[i-1];
}
}
inline void solve(){
int i, j, k;
double frac;
for(i = 0;i < N;++i){
for(j = i+1;j < N;++j)
if(fabs(Eq[i][i]) < fabs(Eq[j][i]))swap(Eq[i], Eq[j]);
if(fabs(Eq[i][i]) < eps){
cout << "No Answer" << endl;
exit(1);
}
for(j = i+1;j < N;++j){
if(fabs(frac = Eq[j][i] / Eq[i][i]) < eps)continue;
Eq[j][i] = 0;
for(k = i+1;k <= N;++k)
Eq[j][k] -= frac * Eq[i][k];
}
}
for(i = N-1;i >= 0;--i){
Ans[i] = Eq[i]
/ Eq[i][i];
for(j = 0;j < i;++j)
Eq[j]
-= Eq[j][i] * Ans[i];
}
for(i = 0;i < N;++i)
printf("%.3lf%c", Ans[i], i == N-1 ? '\n' : ' ');
}
int main(){
#if defined DEBUG
//freopen("test", "r", stdin);
#else
//freopen("bzoj_1013.in", "r", stdin);
//freopen("bzoj_1013.out", "w", stdout);
#endif
init();
solve();
#if defined DEBUG
//cout << endl << (double)clock()/CLOCKS_PER_SEC << endl;
#endif
return 0;
}高斯消元
相关文章推荐
- BZOJ[1013][JSOI2008]球形空间产生器sphere 高斯消元
- [BZOJ 1013][JSOI2008]球形空间产生器sphere(高斯消元)
- [bzoj1013][JSOI2008][球形空间产生器sphere] (高斯消元)
- 【bzoj1013】[JSOI2008]球形空间产生器sphere 高斯消元
- bzoj 1013: [JSOI2008]球形空间产生器sphere(高斯消元)
- 【BZOJ1013】【JSOI2008】球形空间产生器sphere(高斯消元)
- BZOJ 1013 [JSOI2008]球形空间产生器sphere | 高斯消元
- BZOJ 1013 JSOI2008 球形空间产生器sphere 高斯消元
- bzoj 1013: [JSOI2008]球形空间产生器sphere 高斯消元
- bzoj 1013: [JSOI2008]球形空间产生器sphere 高斯消元
- 【高斯消元】bzoj1013 [JSOI2008]球形空间产生器sphere
- [JSOI2008] [BZOJ1013] 球形空间产生器sphere - 高斯消元
- BZOJ 1013: [JSOI2008]球形空间产生器sphere 高斯消元
- bzoj 1013 [JSOI2008]球形空间产生器sphere(高斯消元)
- [高斯消元] BZOJ1013: [JSOI2008]球形空间产生器sphere
- BZOJ1013:[JSOI2008]球形空间产生器sphere (高斯消元)
- 【高斯消元】BZOJ 1013: [JSOI2008]球形空间产生器sphere
- 【BZOJ1013】[JSOI2008]球形空间产生器sphere【高斯消元】
- 【BZOJ 1013】 [JSOI2008]球形空间产生器sphere|高斯消元
- bzoj 1013: [JSOI2008]球形空间产生器sphere(高斯消元)