• [BZOJ 1013] [JSOI2008]球形空间产生器


    [BZOJ 1013] [JSOI2008]球形空间产生器

    题面

    给出一个n维球体上的n+1个点,求球心坐标

    分析

    设球心坐标为((x_1,x_2,dots x_n)),由于一个球体上的所有点到球心距离相等。那么

    (i)个方程为$$ egin{equation} sum_{j=0}^n (a_{i,j}-x_j)^2=C^2 ag{i} end{equation}$$

    其中(C)为距离,(a_{i,j})为点的坐标.我们对相邻两个方程做差,消去(x_j^2)(C). ((i)-(i+1))

    [egin{aligned}sum_{j=1}^n (a_{i,j}^2-a_{i+1,j}^2-2x_j(a_{i,j}-a_{i+1,j})) =0 \sum_{j=1}^n 2(a_{i,j}-a_{i+1,j})x_j =sum_{j=1}^n (a_{i,j}^2-a_{i+1,j}^2)end{aligned} ]

    直接高斯消元即可.

    代码

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #define maxn 10 
    using namespace std;
    int n;
    double a[maxn+5][maxn+5]; 
    double mat[maxn+5][maxn+5];
    void gauss(int n,int m){
    	for(int i=1;i<=n;i++){
    		int id=i;
    		for(int j=i+1;j<=n;j++){
    			if(mat[j][i]>mat[id][i]) id=j;
    		}
    		for(int k=1;k<=m;k++) swap(mat[i][k],mat[id][k]);
    		for(int j=1;j<=n;j++){
    			if(j==i) continue;
    			double r=mat[j][i]/mat[i][i];
    			for(int k=1;k<=m;k++) mat[j][k]-=mat[i][k]*r;
    		}
    	}
    	for(int i=1;i<=n;i++){
    		mat[i][m]/=mat[i][i];
    	}
    } 
    
    int main(){
    	scanf("%d",&n);
    	for(int i=1;i<=n+1;i++){
    		for(int j=1;j<=n;j++){
    			scanf("%lf",&a[i][j]);
    		}
    	}
    	for(int i=1;i<=n;i++){
    		for(int j=1;j<=n;j++){
    			mat[i][j]=2*(a[i][j]-a[i+1][j]); 
    			mat[i][n+1]+=a[i][j]*a[i][j]-a[i+1][j]*a[i+1][j];
    		}
    	}
    	gauss(n,n+1);
    	for(int i=1;i<=n;i++){
    		printf("%.3f ",mat[i][n+1]);
    	}
    } 
    
  • 相关阅读:
    指针
    const
    指针数组和指向数组的指针
    extjs初探之由浅入深目录
    ie6字体设置13px引发的问题
    在IAR下通过Jlink将程序直接下载到Flash指定地址
    提高C语言程序运行稳定性的方法
    C/C++编程习惯
    释放QQ占用的C盘空间
    非阻塞算法思想在关系数据库应用程序开发中的使用
  • 原文地址:https://www.cnblogs.com/birchtree/p/11788026.html
Copyright © 2020-2023  润新知