zoukankan      html  css  js  c++  java
  • [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;
    } 
    
  • 相关阅读:
    高精度计算模板
    P1108 低价购买 [DP][统计方案]
    POJ3349 Snowflake Snow Snowflakes [哈希]
    P1312 Mayan游戏 [深搜][模拟]
    P1378 油滴扩展[深搜]
    P1514 引水入城[搜索,线段覆盖]
    TYVJ1391 走廊泼水节
    【BZOJ1196】公路修建问题
    【BZOJ3624】免费道路
    【BZOJ2429】聪明的猴子
  • 原文地址:https://www.cnblogs.com/PPXppx/p/10588509.html
Copyright © 2011-2022 走看看