点此看题面

大致题意: 给定一个\(n\)维球体上的\(n+1\)个点,请你求出这个球体的圆心的位置。

列出方程

这一看就是一道解方程题

我们可以设这个球体的圆心的位置为\((x_1,x_2,..x_n)\),并设每个点到圆心的距离为\(dis\)。

借助题目中给出的公式,我们可以得到以下方程:

\(\begin{cases}\sqrt{(x_1-a_{1,1})^2+(x_2-a_{1,2})^2+...+(x_n-a_{1,n})^2}=dis\\\sqrt{(x_1-a_{2,1})^2+(x_2-a_{2,2})^2+...+(x_n-a_{2,n})^2}=dis\\......\\\sqrt{(x_1-a_{n+1,1})^2+(x_2-a_{n+1,2})^2+...+(x_n-a_{n+1,n})^2}=dis\end{cases}\)

方程的转化

原方程看起来十分麻烦,又有平方,又有开方,很难解,因此我们要将它转化一下。

将方程两边同时平方,可得:

\(\begin{cases}(x_1-a_{1,1})^2+(x_2-a_{1,2})^2+...+(x_n-a_{1,n})^2=dis^2\\(x_1-a_{2,1})^2+(x_2-a_{2,2})^2+...+(x_n-a_{2,n})^2=dis^2\\......\\(x_1-a_{n+1,1})^2+(x_2-a_{n+1,2})^2+...+(x_n-a_{n+1,n})^2=dis^2\end{cases}\)

但是,这些方程全部都是二次方程,好像非常难做。

因此,我们考虑将每个方程展开:

\(\begin{cases}x_1^2-2a_{1,1}x_1+a_{1,1}^2+x_2^2-2a_{1,2}x_2+a_{1,2}^2+...+x_n^2-2a_{1,n}x_n+a_{1,n}^2=dis^2\\x_1^2-2a_{2,1}x_1+a_{2,1}^2+x_2^2-2a_{2,2}x_2+a_{2,2}^2+...+x_n^2-2a_{2,n}x_n+a_{2,n}^2=dis^2\\......\\x_1^2-2a_{n+1,1}x_1+a_{n+1,1}^2+x_2^2-2a_{n+1,2}x_2+a_{n+1,2}^2+...+x_n^2-2a_{n+1,n}x_n+a_{n+1,n}^2=dis^2\\\end{cases}\)

这时候,我们显然可以看出每个方程中左边都有\(x_1^2+x_2^2+...+x_n^2\),右边都有\(dis^2\),不难想到,将第\(1\sim n\)个方程分别减去第\(n+1\)个方程,便可以得到一个新的方程组,而且是一次的:

\(\begin{cases}2(a_{n+1,1}-a_{1,1})·x_1+...+2(a_{n+1,n}-a_{1,n})·x_n=a_{n+1,1}^2-a_{1,1}^2+...+a_{n+1,n}^2-a_{1,n}^2\\2(a_{n+1,1}-a_{2,1})·x_1+...+2(a_{n+1,n}-a_{2,n})·x_n=a_{n+1,1}^2-a_{2,1}^2+...+a_{n+1,n}^2-a_{2,n}^2\\...\\2(a_{n+1,1}-a_{n,1})·x_1+...+2(a_{n+1,n}-a_{n,n})·x_n=a_{n+1,1}^2-a_{n,1}^2+...+a_{n+1,n}^2-a_{n,n}^2\end{cases}\)

由于\(a\)数组是题目中给出的,我们就可以直接高斯消元了。

代码

#include<bits/stdc++.h>
#define max(x,y) ((x)>(y)?(x):(y))
#define min(x,y) ((x)<(y)?(x):(y))
#define abs(x) ((x)<0?-(x):(x))
#define LL long long
#define ull unsigned long long
#define N 10
using namespace std;
int n;
namespace Gauss
{
const double eps=1e-10;//eps是一个极小值,防止精度误差
double a[N+5][N+5],s[N+5];
inline void swap(double &x,double &y)
{
double t=x;x=y,y=t;
}
inline void GetData()//将读入的数据转化为方程的系数
{
register int i,j;
for(i=1;i<=n+1;++i) for(j=1;j<=n;++j) scanf("%lf",&a[i][j]);
for(i=1;i<=n;++i) for(s[i]=0,j=1;j<=n;++j)
s[i]+=a[n+1][j]*a[n+1][j]-a[i][j]*a[i][j],a[i][j]=2*(a[n+1][j]-a[i][j]);
}
inline void Find_line(int x)//找到一个行数大于等于x且第x个元素系数不为0的方程,将其移至第x行
{
register int i=x,j;
while(i<=n&&fabs(a[i][x])<eps) ++i;
for(j=1;j<=n;++j) swap(a[x][j],a[i][j]);
}
inline void PrintAns()
{
register int i,j,k;
for(i=1;i<=n;++i)
{
for(Find_line(i),j=i+1;j<=n;++j)//消去[i+1~n]中每一行第i个元素
{
register double delta=-a[j][i]/a[i][i];
for(s[j]+=s[i]*delta,k=i;k<=n;++k) a[j][k]+=a[i][k]*delta;
}
}
for(i=n;i;--i) for(s[i]/=a[i][i],j=i-1;j;--j) s[j]-=a[j][i]*s[i];//计算出第i个未知数的值,并将第i个元素的值代入第1~i-1行的式子中消去第i个未知数
for(i=1;i<=n;++i) printf("%.3lf ",s[i]);//输出每一个未知数的值
}
}
int main()
{
return scanf("%d",&n),Gauss::GetData(),Gauss::PrintAns(),0;
}

【BZOJ1013】[JSOI2008] 球形空间产生器(高斯消元)的更多相关文章

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

    题目链接 HDU3571 //824kb 40ms //HDU3571弱化版 跟那个一比这个太水了,练模板吧. //列出$n+1$个二次方程后两两相减,就都是一次方程了. #include <c ...

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

    题目描述 有一个\(n\)维空间中的球,告诉你球面上\(n+1\)个点的坐标,求球心的坐标. \(n\leq 10\) 题解 设\(a_{i,j}\)为第\(i\)个点的第\(j\)维坐标,\(i=0 ...

  3. LG4035/BZOJ1013 「JSOI2008」球形空间产生器 高斯消元

    问题描述 LG4035 BZOJ1013 题解 设答案为\((p_1,p_2,p_3,...,p_n)\) 因为是一个球体,令其半径为\(r\),则有 \[\sum_{i=1}^{n}{(a_i-p_ ...

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

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

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

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

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

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

  7. bzoj千题计划104:bzoj1013: [JSOI2008]球形空间产生器sphere

    http://www.lydsy.com/JudgeOnline/problem.php?id=1013 设球心(x1,x2,x3……) 已知点的坐标为t[i][j] 那么 对于每个i满足 Σ (t[ ...

  8. bzoj1013 [JSOI2008]球形空间产生器

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

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

    传送门 高斯消元练习. 模板: void Guass(){ int waited; up(i,1,N){ waited=i; up(j,i+1,N)if(fabs(M[j][i])>fabs(M ...

  10. BZOJ1013 [JSOI2008]球形空间产生器sphere[高消]

    数论进度开的好慢啊.我整天做的都是什么鬼题啊. 简单的高消题,用一个式子把另外$n$个有二次项和距离的式子全消掉就行了. #include<iostream> #include<cs ...

随机推荐

  1. 2017乌鲁木齐区域赛A(动态规划,组合数学,期望)

    #include<bits/stdc++.h>using namespace std;double c[110][110];double g[110];double dp[110][110 ...

  2. python之01电脑和操作系统简史

    电脑简史 早期计算方式发展 :手指和石头 ->结绳 ->算筹->计算尺 -> 算盘 19岁时(1642),帕斯卡发明了人类有史以来第一台机械计算机——帕斯卡加法器.它是一种系列 ...

  3. Python中的矩阵、多维数组:Numpy

    Numpy 是Python中科学计算的核心库.它提供一个高性能多维数据对象,以及操作这个对象的工具.部分功能如下: ndarray, 具有矢量算术运算和复杂广播能力的快速且节省空间的多维数组. 用于对 ...

  4. 洛谷P1312 Mayan游戏

    P1312 Mayan游戏 题目描述 Mayan puzzle是最近流行起来的一个游戏.游戏界面是一个 7 行5 列的棋盘,上面堆放着一些方块,方块不能悬空堆放,即方块必须放在最下面一行,或者放在其他 ...

  5. MySQL的高可用实现:MySQL系列之十四

    MySQL的高可以有三种实现方式:多主模式(Multi Master MySQL),MHA(Master High Availability)和 Galera Cluster:wresp 一.MHA ...

  6. js抽奖系统

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  7. LeetCode初级算法(数组)解答

    这里记录了LeetCode初级算法中数组的一些题目: 加一 本来想先转成整数,加1后再转回去:耽美想到测试的例子考虑到了这个方法的笨重,所以int类型超了最大范围65536,导致程序出错. class ...

  8. POJ 2796:Feel Good 单调栈

    题目,给定一个数列,n <= 1e5 .要求找出一个区间,使得其内区间最小值 * 区间总和的值最大,要求输出区间. 首先先维护一个单调递增的栈,同时记录一个lef值表示:lef[i]表示当前栈内 ...

  9. Maven插件和细节

    1.父工程统一版本号 <!-- 集中定义依赖版本号 --> <properties> <junit.version>4.12</junit.version&g ...

  10. 精心收集的SSH框架的面试题汇总

    Hibernate工作原理及为什么要用? 原理: 1. 读取并解析配置文件 2. 读取并解析映射信息,创建SessionFactory 3. 打开Sesssion 4. 创建事务Transation ...