• [JSOI2008]球形空间产生器


    洛咕

    题意:有一个n维球体,你知道球面上n+1个点的坐标,你需要确定这个n维球体的球心坐标.

    分析:对于一个球,球面上任意一点到球心的距离都是相等的,我们可以根据这条性质,列出n+1个方程。但方程右边全都是半径,而半径我们正好又不知道,所以可以通过相邻两个方程相减从而消去半径,同时也构造出了我们熟悉的n个n元一次方程。直接高斯消元(my学习笔记)

    #include<bits/stdc++.h>
    using namespace std;
    double a[20][20],b[20][20];
    int main(){
        int n;cin>>n;
        for(int i=1;i<=n+1;i++)
        	for(int j=1;j<=n;j++)
            	scanf("%lf",&a[i][j]);
    //读入n+1个点的n维坐标
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++){
                b[i][j]=2*(a[i][j]-a[i+1][j]);
    //因为点的坐标^2-球心坐标^2=半径^2,化简一下就会有个乘2
                b[i][n+1]+=(a[i][j]*a[i][j]-a[i+1][j]*a[i+1][j]);
            }		
    //构造出n个n元一次方程
        for(int i=1;i<=n;i++){//高斯消元的模板
    			int now=i;
    			for(int j=i+1;j<=n;j++)
    				if(fabs(b[now][i])<fabs(b[j][i]))now=j;
    			if(now!=i){
    				for(int j=i;j<=n+1;j++)
    					swap(b[i][j],b[now][j]);
    			}
    			for(int j=i+1;j<=n+1;j++)
    				b[i][j]/=b[i][i];
    			b[i][i]=1;
    			for(int j=i+1;j<=n;j++){
    				for(int k=i+1;k<=n+1;k++)
    					b[j][k]-=b[j][i]*b[i][k];
    				b[j][i]=0;
    			}	 
    	}	
    	for(int i=n;i>=1;i--){
    		for(int j=i+1;j<=n;j++){
    			b[i][n+1]-=b[i][j]*b[j][n+1];
    			b[i][j]=0;
    		}
    	}
    	for(int i=1;i<=n;i++)
    		printf("%.3lf ",b[i][n+1]);
       return 0;
    } 
    
  • 相关阅读:
    设计模式
    LintCode 数组(一)
    LintCode 字符串(二)
    LintCode 字符串(一)
    Java 多线程---volatile, ThreadLocal
    HTTP之缓存首部
    HTTP之首部
    HTTP之状态码
    web安全之XSS和CSRF
    web安全之同源策略
  • 原文地址:https://www.cnblogs.com/PPXppx/p/10588509.html
Copyright © 2020-2023  润新知