• lydsy1013: [JSOI2008]球形空间产生器sphere 高斯消元


    题链:http://www.lydsy.com/JudgeOnline/problem.php?id=1013


    1013: [JSOI2008]球形空间产生器sphere

    时间限制: 1 Sec  内存限制: 162 MB
    提交: 3063  解决: 1607
    [提交][][]

    题目描写叙述

    有一个球形空间产生器可以在n维空间中产生一个坚硬的球体。如今,你被困在了这个n维球体中。你仅仅知道球面上n+1个点的坐标。你须要以最快的速度确定这个n维球体的球心坐标。以便于摧毁这个球形空间产生器。

    输入

    第一行是一个整数,n。接下来的n+1行,每行有n个实数,表示球面上一点的n维坐标。每个实数精确到小数点后6位,且其绝对值都不超过20000。

    输出

    有且仅仅有一行。依次给出球心的n维坐标(n个实数),两个实数之间用一个空格隔开。每一个实数精确到小数点后3位。数据保证有解。

    你的答案必须和标准输出一模一样才可以得分。

    例子输入

    2
    0.0 0.0
    -1.0 1.0
    1.0 0.0

    例子输出

    0.500 1.500

    提示

    数据规模:

    对于40%的数据,1<=n<=3

    对于100%的数据,1<=n<=10

    提示:给出两个定义:

    1、 球心:到球面上随意一点距离都相等的点。

    2、 距离:设两个n为空间上的点A, B的坐标为(a1, a2, …, an), (b1, b2, …, bn),则AB的距离定义为:dist = sqrt( (a1-b1)^2 + (a2-b2)^2 + … + (an-bn)^2 )



    做法:把圆心坐标设成 x1,x2,x3.... ,有若干个点  当中两个点坐标为a1,a2, a3....    和b1,b2,b3.

    能够写出方程

    sqrt((a1-x1)^2+(a2-x2)^2+(a3-x3)^2)=sqrt((b1-x1)^2+(b2-x2)^2+(b3-x3)^2)

    两边去根号。

    (a1-x1)^2+(a2-x2)^2+(a3-x3)^2=(b1-x1)^2+(b2-x2)^2+(b3-x3)^2

    把平分打开

    a1^2+x1^2+a2^2+x2^2+a3^2+x3^2-2*a1*x1-2*a2*x2-2*a3*x3=b1^2+x1^2+b2^2+x2^2+b3^2+x3^2-2*b1*x1-2*b2*x2-2*b3*x3

    整理下 把x的二次方 两边都减去。把x的一次放左边 0次项放右边。

    -2*a1*x1-2*a2*x2-2*a3*x3+2*b1*x1+2*b2*x2+2*b3*x3=b1^2+b2^2+b3^2-a1^2-a2^2-a3^2

    整理下

    (-2*a1+2*b1)*x1+(-2*a2+2*b2)*x2+(-2*a3+2*b3)*x3=b1^2+b2^2+b3^2-a1^2-a2^2-a3^2

    一共同拥有n+1个点,所以能够写出n条这种等式。

    最后的形式就是AX=b了, 然后就能够高斯消元了。


    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <limits.h>
    #include <malloc.h>
    #include <ctype.h>
    #include <math.h>
    #include <string>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    #include <stack>
    #include <queue>
    #include <vector>
    #include <deque>
    #include <set>
    #include <map>
    
    #define eps 1e-9
    const int MAXN=220;
    double a[MAXN][MAXN],x[MAXN];//方程的左边的矩阵和等式右边的值,求解之后x存的就是结果
    int equ,var;//方程数和未知数个数
    /*
    *返回0表示无解。1表示有解
    */
    int Gauss()
    {
    	int i,j,k,col,max_r;
    	for(k=0,col=0;k<equ&&col<var;k++,col++)
    	{
    		max_r=k;
    		for(i=k+1;i<equ;i++)
    			if(fabs(a[i][col])>fabs(a[max_r][col]))
    				max_r=i;
    		if(fabs(a[max_r][col])<eps)return 0; 
    			if(k!=max_r)
    			{
    				for(j=col;j<var;j++)
    					swap(a[k][j],a[max_r][j]);
    				swap(x[k],x[max_r]);
    			}
    			x[k]/=a[k][col];
    			for(j=col+1;j<var;j++)a[k][j]/=a[k][col];
    			a[k][col]=1;
    			for(i=0;i<equ;i++)
    				if(i!=k)
    				{
    					x[i]-=x[k]*a[i][k];
    					for(j=col+1;j<var;j++)a[i][j]-=a[k][j]*a[i][col];
    					a[i][col]=0;
    				}
    	}
    	return 1;
    }
    
    double dian[13][13];
    int main()
    {
    	int n;
    	while(scanf("%d",&n)!=EOF)
    	{
    		for(int i=0;i<n+1;i++) 
    			for(int j=0;j<n;j++)
    				scanf("%lf",&dian[i][j]);  
    		equ=n;
    		var=n;
    		memset(x,0,sizeof x);
    		for(int i=0;i<n;i++)
    		{
    			for(int j=0;j<n;j++)
    				a[i][j]=-2.0*dian[i][j]+2*dian[i+1][j];
    			for(int j=0;j<n;j++)
    				x[i]+=dian[i+1][j]*dian[i+1][j]-dian[i][j]*dian[i][j];
    		}
    		Gauss();
    		for(int i=0;i<n;i++)
    		{
    			if(i!=0)
    				printf(" ");
    			printf("%.3lf",x[i]);
    		}
    	}
    	return 0;
    }







  • 相关阅读:
    ZYB建围墙
    换根DP
    原码,反码,补码的计算
    字符串游戏-博弈论-trie
    【十连赛day8】神炎皇
    生成序列
    【USACO 2006 February Silver】产奶安排Stall Reservations-贪心
    tar 压缩解压命令
    java 注解
    回溯算法解决全排列问题
  • 原文地址:https://www.cnblogs.com/lxjshuju/p/7136635.html
Copyright © 2020-2023  润新知