• P4035 [JSOI2008]球形空间产生器


    P4035 [JSOI2008]球形空间产生器

    题目

    题目大意

    给出n维空间上的n+1个点,且这些店都在一个圆的表面,求圈心坐标.

    定义:

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

    2. 两点间距离公式

    [A(x_1,x_2,x_3,x_4,cdots x_n) ]

    [B(y_1,y_2,y_3,y_4,cdots y_n) ]

    [distance:sqrt[2]{sum_{i=1}^{n}(x_i-y_i)^2} ]


    题目看上去应该就是解方程了。

    我们可以使用gauss消元法

    不过问题就来了。这是一个二次多元方程组。而我们的gauss只能解决一次。而且gauss的前提是有n个未知数,我们必须有n个方程。(当然有些不严谨

    我们就要考虑移项和再设一个未知数

    原方程中的一个:我们先设一个数,r。表示根据圆的标准方程算出来的半径
    A为一个点,R为圆心

    [A(x_1,x_2,x_3,x_4,cdots x_n) ]

    [R(y_1,y_2,y_3,y_4,cdots y_n) ]

    [sum_{i=1}^{n}(x_i-y_i)^2=r^2 ]

    [sum_{i=1}^{n}x_i^2-sum_{i=1}^{n}2x_iy_i+sum_{i=1}^{n}y_i^2=r^2 ]

    请注意这里的A的坐标都是已知量。而r和R的坐标不是

    然后我们移项

    [-sum_{i=1}^{n}2x_iy_i+(sum_{i=1}^{n}y_i^2-r^2)=-sum_{i=1}^{n}x_i^2 ]

    最绕的一步来了
    我们将括号内的整体代换(或看成一个未知数)

    这样就有n+1个未知数来了。而且我们解出方程来后,我们只需要前n个未知数。后面我们后面设的未知数虽然解出来了。但是没有什么用。只是我们一个辅助变量

    同时,这个题也告诉我们一些小技巧。

    1. 出题人不可能多给条件。有些是要我们自己设的
    2. 遇到二次方程。可以考虑拆括号和移项。然后进行还原达到降幂的目的
    #include<cstdio> 
    #include<algorithm>
    #include<iostream>
    #include<cmath>
    using namespace std;
    double map[15][15];
    double ans[15];
    int n;
    void gauss()
    {
    	for(int i=1;i<=n+1;i++)
    	{
    		int r=i;
    		for(int j=i+1;j<=n+1;j++)
    			if(fabs(map[r][i])<fabs(map[j][i]))
    				r=j;
    		if(r!=i)
    			for(int j=i;j<=n+2;j++)
    				swap(map[i][j],map[r][j]);
    		double div=map[i][i]; 
    		for(int j=i;j<=n+2;j++)
    			map[i][j]/=div;
    		for(int j=i+1;j<=n+1;j++)
    		{
    			div=map[j][i];
    			for(int k=i;k<=n+2;k++)
    				map[j][k]-=div*map[i][k];
    		}
    	}
    	ans[n+1]=map[n+1][n+2];
    	for(int i=n;i>=1;i--)
    	{
    		ans[i]=map[i][n+2];
    		for(int j=i+1;j<=n+1;j++)
    			ans[i]-=map[i][j]*ans[j];
    	}
    }
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n+1;i++)
    	{
    		double data;
    		for(int j=1;j<=n;j++) 
    		{
    			scanf("%lf",&data);
    			map[i][j]=-2.0*data;
    			map[i][n+2]-=data*data;
    		}
    		map[i][n+1]=1;
    	}
    	gauss();
    	printf("%.3lf",ans[1]);
    	for(int i=2;i<=n;i++)
    		printf(" %.3lf",ans[i]);
    }
    
  • 相关阅读:
    iOS 将对象的属性和属性值拆分成key、value,通过字符串key来获取该属性的值
    [IOI2005] Riv 河流
    [洛谷P4549] [模板] 裴蜀定理
    [NOIp2013] 货车运输
    [NOIp2015] 运输计划
    18.10.01模拟赛总结
    [洛谷P3369] 普通平衡树 Treap & Splay
    [NOIp2016] 组合数问题
    [洛谷P4777] [模板] 扩展中国剩余定理
    [洛谷P3384] [模板] 树链剖分
  • 原文地址:https://www.cnblogs.com/Lance1ot/p/8970792.html
Copyright © 2020-2023  润新知