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


    题目描述

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

    输入输出格式

    输入格式:

     

    第一行是一个整数 n(1<=N=10)(1<=N=10) 。接下来的 n+1n+1 行,每行有 nn 个实数,表示球面上一点的 nn 维坐标。每一个实数精确到小数点后 66 位,且其绝对值都不超过 2000020000 。

     

    输出格式:

     

    有且只有一行,依次给出球心的 nn 维坐标( nn 个实数),两个实数之间用一个空格隔开。每个实数精确到小数点后 33 位。数据保证有解。你的答案必须和标准输出一模一样才能够得分。

     

    输入输出样例

    输入样例#1: 
    2
    0.0 0.0
    -1.0 1.0
    1.0 0.0
    输出样例#1: 
    0.500 1.500

    说明

    提示:给出两个定义:

      1. 球心:到球面上任意一点距离都相等的点。
      2. 距离:设两个n为空间上的点A, B的坐标为 (a_1, a_2, cdots , a_n), (b_1, b_2, cdots , b_n)(a1,a2,,an),(b1,b2,,bn) ,则AB的距离定义为: dist = sqrt{ (a_1-b_1)^2 + (a_2-b_2)^2 + cdots + (a_n-b_n)^2 }dist=(a1b1)2+(a2b2)2++(an​−bn​)2​

    Solution:

      我们所求的是$n$维的球心坐标,可以肯定的是$forall i,iin[1,n+1]$,都有$sumlimits_{j=1}^{jleq n}{(o_j-x_{ij})^2}=R^2$其中$o$为圆心、$R$是个常数代表半径。

      题目中给了$n+1$个这样的式子,我们相邻的两式相减,就能得到$n$个消去了$R$的等式$sumlimits_{j=1}^{jleq n}{[(o_j-x_{ij})^2+(o_j-x_{i+1j})^2]}=0$,展开可以得到$sumlimits_{j=1}^{jleq n}{[2*o_j*(x_{ij}-x_{i+1j})]}=sumlimits_{j=1}^{jleq n}{(x_{ij}^2-x_{i+1j}^2)}$,等式左边我们直接作为$n$个$n$元方程,右边就是每个方程所对应的常数。

      处理出这个$n$元方程组,直接高斯消元求解就好了。

    代码:

    #include<bits/stdc++.h>
    #define il inline
    #define ll long long
    #define For(i,a,b) for(int (i)=(a);(i)<=(b);(i)++)
    #define Bor(i,a,b) for(int (i)=(b);(i)>=(a);(i)--)
    using namespace std;
    const int N=25;
    int n,now;
    double a[N][N],b[N][N];
    
    int main(){
        scanf("%d",&n);
        For(i,1,n+1) For(j,1,n) scanf("%lf",&b[i][j]);
        For(i,1,n) For(j,1,n) {
            a[i][j]=2*(b[i][j]-b[i+1][j]);
            a[i][n+1]+=(b[i][j]*b[i][j]-b[i+1][j]*b[i+1][j]);
        }
        For(i,1,n) {
            now=i;
            For(j,i+1,n) if(fabs(a[j][i])>fabs(a[now][i]))now=j;
            if(now!=i) For(j,i,n+1) swap(a[now][j],a[i][j]);
            For(k,i+1,n){
                double t=a[k][i]/a[i][i];
                For(j,i,n+1) a[k][j]-=a[i][j]*t;
            }
        }
        Bor(i,1,n){
            For(j,i+1,n) a[i][n+1]-=a[j][n+1]*a[i][j];
            a[i][n+1]/=a[i][i];
        }
        For(i,1,n) printf("%.3lf ",a[i][n+1]);
        return 0;
    }
  • 相关阅读:
    LintCode "Subarray Sum II"
    LintCode "Maximum Subarray Difference"
    LeetCode "Flip Game II"
    LintCode "Sliding Window Median" & "Data Stream Median"
    LintCode "Permutation Index"
    LintCode "Count of Smaller Number before itself"
    LeetCode "Nim Game"
    Etcd在Linux CentOS7下载、安装
    CentOS7 查看开启端口
    CentOS7-防火墙firewall 状态、重启、关闭
  • 原文地址:https://www.cnblogs.com/five20/p/9362948.html
Copyright © 2020-2023  润新知