洛谷 4035 [JSOI2008]球形空間產生器


題目戳這里
一句話題意

給你 n+1 個 n 維點,需要你求出這個n維球的球心。(n<=10)

Solution

這個題目N維的話確實不好想,反正三維就已經把我搞懵了,所以只好拿二維類比。
首先因為球心到邊上的點距離相等,所以我們可以列出三個式子:
設 球心坐標為(\(x_0\)\(y_0\))
\((x_1-x_0)^2+(y_1-y_0)^2=r^2\)

\((x_2-x_0)^2+(y_2-y_0)^2=r^2\)

\((x_3-x_0)^2+(y_3-y_0)^2=r^2\)
三個式子中都有r和平方項不好計算,所以我們用1式減2式,2式減3式,就得到兩個式子:
\(x_1^2-x_2^2-2x_1x_0+2x_2x_0+y_1^2-y_2^2-2y_1y_0+2y_2y_0=0\)

\(x_2^2-x_3^2-2x_2x_0+2x_3x_0+y_2^2-y_3^2-2y_2y_0+2y_3y_0=0\)
\(x_1,y_1,x_2,y_2,x_3,y_3\)都是已知的,可以看成常數項和系數。
再整理一下:
\(2(x_2-x_1)x_0+2(y_2-y_1)y_0=x_2^2-x1^2+y_2^2-y_1^2\)

\(2(x_3-x_2)x_0+2(y_3-y_2)y_0=x_3^2-x2^2+y_3^2-y_2^2\)
很明顯一個二元一次方程組,然后使用高斯消元就可以求出球心。
這樣就很容易推到N維了,這里就不一一寫出,大家自己手推一下吧。主要是太麻煩了

Coding

#include<bits/stdc++.h>
using namespace std;
const int N = 105;
double s[N][N],ans[N],A[N][N];
int n,flag=1;
void Solve(int x)
{
  if(x==n){  ans[x]=s[x][n+1]/s[x][x]; return; }
  for(int i=x+1;i<=n;i++)
  {
    double box=abs(s[x][x])/abs(s[i][x]);
    if(s[x][x]*s[i][x]>0)
      for(int j=x;j<=n+1;j++)
        s[i][j]*=box,s[i][j]=s[i][j]-s[x][j];
    else
      for(int j=x;j<=n+1;j++)
        s[i][j]*=box,s[i][j]=s[i][j]+s[x][j];
  }
  Solve(x+1);
  for(int i=n;i>=x+1;i--)
  	s[x][n+1]-=(ans[i]*s[x][i]); 
  ans[x]=s[x][n+1]/s[x][x];
  return ;
}
int main()
{
    cin>>n;
    for(int i=1;i<=n+1;i++)
        for(int j=1;j<=n;j++)
        scanf("%lf",&A[i][j]);
    for(int i=2;i<=n+1;i++)
        for(int j=1;j<=n;j++)
        {
            s[i-1][j]=2*(A[i][j]-A[i-1][j]);
            s[i-1][n+1]+=(A[i][j]*A[i][j]-A[i-1][j]*A[i-1][j]);
        }
    Solve(1);
    for(int i=1;i<=n;i++)
    printf("%.3lf ",ans[i]);
    return 0;
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM