[BZOJ 1013][JSOI 2008] 球形空间产生器sphere

Description

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

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

Input

第一行是一个整数n(1<=N=10)。接下来的n+1行,每行有n个实数,表示球面上一点的n维坐标。每一个实数精确到小数点

后6位,且其绝对值都不超过20000。

Output

有且只有一行,依次给出球心的n维坐标(n个实数),两个实数之间用一个空格隔开。每个实数精确到小数点

后3位。数据保证有解。你的答案必须和标准输出一模一样才能够得分。

Solution

1.考虑构造对于不同的店同样结构的方程。

因为是一个球,所以每个点到球心的距离都相等,

我们设这个半径为R,球心坐标为O(x1,x2,....,xn);

那么对于每一个点P(ai1,ai2,...,ain):我们易得

sqrt ( ( ai1 - x1 ) ^ 2 + ( ai2 - x2 ) ^ 2 + ... + ( ain - xn ) ^2 ) = R;

2.考虑构造方程组

将上式两侧平方再展开,得

-2 ( ai1 * x1 + ai2 * x2 + ... + ain * xn )

+( ai1 ^ 2 + ai2 ^ 2 + ... + ain ^ 2 )

+( x1 ^ 2 + x2 ^ 2 + ... + xn ^ 2 )

= R ^ 2;

这时我们看数据,给出n+1个点,n个点就可以构造该方程组,那多给的一个点是用来干什么的呢(设选第一个点为这个点)?

没错!消掉重复出现的部分( x1 ^ 2 + x2 ^ 2 + ... + xn ^ 2 ) 和R ^ 2,

即令其他所有的点的方程都减掉多的一个点的方程,整理得到其他方程格式为:

2 ( ai1 * x1 + ai2 * x2 + ... + ain * xn )

= ( ai1 ^ 2 + ai2 ^ 2 + ... + ain ^ 2 )

- ( a11 ^ 2 + a12 ^ 2 + ... + a1n ^ 2 )

- 2 ( a11 * x1 + a12 * x2 + ... + a1n * xn ) ;

右侧是常数,左侧展开就是一个愉快的高斯消元方程组,解方程组即可。

这里使用的高斯消元法是一种比较毒瘤的方法,详解参考我的随笔:http://www.cnblogs.com/COLIN-LIGHTNING/p/8981923.html

Code

  1. #include<iostream>
  2. #include<cstdio>
  3. #include<cmath>
  4. #include<cstring>
  5. #include<algorithm>
  6. using namespace std;
  7. const int max_n=15;
  8. double a[max_n][max_n+1],v[max_n],del[max_n],x;
  9. int n,w[max_n];
  10. inline double sqr(double x){return x*x;}
  11. void init(){
  12. for(int i=1;i<=n;++i)scanf("%lf",&del[i]);
  13. for(int i=1;i<=n;++i){
  14. for(int j=1;j<=n;++j){
  15. scanf("%lf",&x);
  16. a[i][n+1]+=sqr(x)-sqr(del[j]);
  17. a[i][j]=2*(x-del[j]);
  18. }
  19. }
  20. }
  21. void gauss(){
  22. double eps=1e-6;
  23. for(int i=1;i<=n;++i){//enumerate the equation;
  24. int p=0; //Record the position of the largest number;
  25. double mx=0; //Recording the largest number;
  26. for(int j=1;j<=n;++j)
  27. if(fabs(a[i][j])-eps>mx){
  28. mx=fabs(a[i][j]);p=j;//fabs() returns the absolute value of float;
  29. }
  30. w[i]=p;
  31. for(int j=1;j<=n;++j)
  32. if(i!=j){ //other equations
  33. double t=a[j][p]/a[i][p];
  34. for(int k=1;k<=n+1;++k)//n+1 is important
  35. a[j][k]-=a[i][k]*t;
  36. }
  37. }
  38. for(int i=1;i<=n;++i) v[w[i]]=a[i][n+1]/a[i][w[i]];
  39. for(int i=1;i<=n;++i) printf("%.3lf ",v[i]);
  40. }
  41. int main(){
  42. scanf("%d",&n);
  43. init();
  44. gauss();
  45. return 0;
  46. }

[BZOJ 1013][JSOI 2008] 球形空间产生器sphere 题解(高斯消元)的更多相关文章

  1. bzoj 1013 [JSOI2008]球形空间产生器sphere(高斯消元)

    1013: [JSOI2008]球形空间产生器sphere Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 3584  Solved: 1863[Subm ...

  2. 【BZOJ 1013】球形空间产生器sphere(高斯消元)

    球形空间产生器sphere HYSBZ - 1013 (高斯消元) 原题地址 题意 给出n维的球上的n个点,问原球体球心. 提示 n维球体上两点距离公式\(dist = \sqrt{ (a1-b1)^ ...

  3. 【BZOJ1013】【JSOI2008】球形空间产生器sphere(高斯消元)

    1013: [JSOI2008]球形空间产生器sphere Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 1600  Solved: 860[Submi ...

  4. BZOJ1013 [JSOI2008]球形空间产生器sphere(高斯消元)

    1013: [JSOI2008]球形空间产生器sphere Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 4846  Solved: 2525[Subm ...

  5. BZOJ1013 JSOI2008 球形空间产生器sphere 【高斯消元】

    BZOJ1013 JSOI2008 球形空间产生器sphere Description 有一个球形空间产生器能够在n维空间中产生一个坚硬的球体.现在,你被困在了这个n维球体中,你只知道球面上n+1个点 ...

  6. _bzoj1013 [JSOI2008]球形空间产生器sphere【高斯消元】

    传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1013 保存高斯消元模版. ps,这一题的英文名字是ヨスガノソラ的开发商~^_^ #inclu ...

  7. 【BZOJ】1013 [JSOI2008]球形空间产生器sphere(高斯消元)

    题目 传送门:QWQ 分析 高斯消元就是个大暴力.... 代码 #include <bits/stdc++.h> using namespace std; ; ; int n; doubl ...

  8. bzoj 1013: [JSOI2008]球形空间产生器sphere【高斯消元】

    n+1个坐标可以列出n个方程,以二维为例,设圆心为(x,y),给出三个点分别是(a1,b1),(a2,b2),(a3,b3) 因为圆上各点到圆心的距离相同,于是可以列出距离方程 \[ (a1-x)^2 ...

  9. 【BZOJ 1013】 [JSOI2008]球形空间产生器sphere

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

随机推荐

  1. Delphi中 弹出框的用法

    Delphi中的提示框有 Application.MessageBox  ShowMessage messagedlg 个人认为 相对来说 Application.MessageBox 更加灵活 也相 ...

  2. VSTS写单元测试

                          用VSTS写单元测试                           许多应用程序都会用到“用户”类型,今天我要用的是ConsoleApplicatio ...

  3. Alpha冲刺——day10

    Alpha冲刺--day10 作业链接 Alpha冲刺随笔集 github地址 团队成员 031602636 许舒玲(队长) 031602237 吴杰婷 031602220 雷博浩 031602634 ...

  4. Linux命令(十二) 分割文件 split 合并文件 join

    一.分割文件 split 命令介绍 当处理文件时,有时需要将文件做分割处理,split 命令用于分割文件,可以分割文本文件,按指定的行数分割,每个分割后的文件都包含相同的行数.split 可以分割非文 ...

  5. 【转帖】Git学习笔记 记录一下

    本文内容参考了廖雪峰老师的博文,并做了适当整理,方便大家查阅. 原帖地址 https://wangfanggang.com/Git/git/ 常用命令 仓库初始化 - git init 1 git i ...

  6. PSP(4.13——4.19)以及周记录

    1.PSP 4.13 15:15 15:30 0 15 站立会议 A Y min 15:30 19:00 65 145 Account A Y min 21:15 23:00 15 90 博客 B Y ...

  7. SSM项目POST中文乱码解决方案

    在本地搞了一个SSM的项目练手,修改数据的时候,提交中文数据后居然乱码了.网上一顿狂搜,最终花了几个小时终于解决. 遂加以记录,以便不时之需. 就这么个表单,如果提交中文修改就会乱码,首先确定项目和数 ...

  8. 解决sublime text3下中文无法输入的问题(Ubuntu)

    sublime-text-imfix,非常无脑.就喜欢这样的.

  9. delphi制作登陆窗体

    delphi登陆窗体的制作,就我知道的,可以有两种方法,一种是在工程文件中实现登陆窗体的动态调用,另一种就是在主窗体的OnCreate事件中动态创建登陆窗体,两种方法都需要将主窗体设置为Auto-cr ...

  10. OpenCV学习(23) 使用kmeans算法实现图像分割

          本章我们用kmeans算法实现一个简单图像的分割.如下面的图像,我们知道图像分3个簇,背景.白色的任务,红色的丝带以及帽子.       Mat img = cv::imread(&quo ...