zoukankan      html  css  js  c++  java
  • [bzoj1013][JSOI2008]球形空间产生器

    Description

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

    Input

    第一行是一个整数\(n(1\leq{N}\leq10)\).
    接下来的\(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
    

    Sample Output

    0.500 1.500
    

    HINT

    1. 球心:到球面上任意一点距离都相等的点.
    2. 距离:设两个\(n\)为空间上的点\(A,B\)的坐标为\((a_1,a_2,\dots,a_n),(b_1,b_2,\dots,b_n)\),则\(AB\)的距离定义为:\(dist=\sqrt{(a_1-b_1)^2 +(a_2-b_2)^2+\dots+(a_n-b_n)^2}\).

    Solution

    设球心坐标为\((x_1,x_2,\dots,x_n)\),
    球面上点的坐标为\((y_{1,i},y_{2,i},\dots,y_{3,i})\),
    \(\sum(y_{i,j}-x_i)^2=C\).
    所以\(\sum(y_{i,j}-x_i)^2=\sum(y_{i,j+1}-x_i)^2\).
    因为\(\sum(y_{i,j}-x_i)^2=\sum(y_{i,j}^2-2\times{y_{i,j}}\times{x_i}+x_i^2)\)
    所以\(\sum(y_{i,j}^2-2\times{y_{i,j}}\times{x_i}+x_i^2)=\sum(y_{i,j+1}^2-2\times{y_{i,j+1}}\times{x_i}+x_i^2)\)
    所以\(\sum(2\times{x_i}\times(y_{i,j+1}-y_{i,j}))=\sum(y_{i,j+1}^2-y_{i,j}^2)\).
    就可以用高斯消元求解了.

    #include<cmath>
    #include<queue>
    #include<stack> 
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #define N 20
    #define F 1e-13
    using namespace std;
    double a[N][N],b[N][N],ans[N];
    int n;
    inline void gauss(){
    	double tmp;
    	for(int i=1;i<=n;++i){
    		if(fabs(a[i][i])<eps) 
    			for(int j=i+1;j<=n;++j)
    				if(a[j][i]){
    					for(int k=i;k<=n+1;++k)
    						swap(a[i][k],a[j][k]);
    					break;
    				}
    		for(int j=1;j<=n;++j)
    			if(j!=i&&fabs(a[j][i])>0){
    				tmp=a[j][i]/a[i][i];
    				for(int k=i;k<=n+1;++k)
    					a[j][k]=a[j][k]-tmp*a[i][k];
    			}
    	}
    	for(int i=1;i<=n;++i)
    		ans[i]=a[i][n+1]/a[i][i];
    }
    inline void Aireen(){
        scanf("%d",&n);
        for(int i=1;i<=n+1;++i){
            for(int j=1;j<=n;++j)
                scanf("%lf",&b[i][j]);
        }
        for(int i=1;i<=n;++i)
            for(int j=1;j<=n;++j){
                a[i][j]=2.0*(b[i][j]-b[i+1][j]);
                a[i][n+1]+=pow(b[i][j],2)-pow(b[i+1][j],2);
            }
        gauss();
        for(int i=1;i<n;++i)
            printf("%.3lf ",ans[i]);
        printf("%.3lf\n",ans[n]);
    }
    int main( ) {
        freopen("sphere.in","r",stdin);
        freopen("sphere.out","w",stdout);
        Aireen();
        fclose(stdin);
        fclose(stdout);
        return 0;
    }
    

    2017-03-06 20:28:54

  • 相关阅读:
    asList和subList的缺陷
    oracle和mysql的拼接查询
    Google Guava的splitter用法
    docker创建mongodb并且测试代码
    GitHub 近两万Star,无需编码,可一键生成前后端代码,这个开源项目JeecgBoot有点强
    在深圳养一个娃需要多少钱?2020深圳养娃开销(Excel文本)清单公布!家长直呼扎心了!
    Win7安装AD域管理工具-Win7安装AD域远程服务器管理工具
    盘点2020年那些大厂网盘小厂网盘其他网络存储设备
    完美解决远程计算机需要网络级别身份验证RDO
    OPPO手机的指令合集(工程模式、串号等)
  • 原文地址:https://www.cnblogs.com/AireenYe/p/bzoj1013.html
Copyright © 2011-2022 走看看