bzoj 1013 高斯消元

题意:n维空间中,给出球面上(n+1)个点的坐标,求出球心坐标,输出保留三位小数,比较时不忽略行末空格(答案输出必须和标准输出一模一样)

显然,球面上的点到球心的距离相等,等于半径长

假设我们知道一个点的坐标为 : a1,a2,a3,....,an; 另一点坐标为: b1,b2,b3,...,bn

设 球心坐标为 x1,x2,x3,...,xn; 半径为r

那么,我们可以列出方程组:(a1-x1)^2 + (a2-x2)^2+...+ (an-xn)^2 = r^2  ①

                                              (b1-x1)^2 + (b2-x2)^2+...+ (bn-xn)^2 = r^2  ②

 ①-② 得

                       (a1-b1)*(a1+b1-2x1) + (a2-b2)*(a2+b2-2x2) +...+ (an-bn)*(an+bn-2xn) = 0

  a1^2-b1^2 - 2x1*(a1-b1) + a2^2 - b2^2 - 2x2*(a2-b2)+...+ an^2 - bn^2 -2xn(an-bn)=0

(把常数移到等号右边,未知数留到等号左边)

 -2x1*(a1-b1) - 2x2*(a2-b2) -... - 2xn*(an-bn) = - (a1^2-b1^2 + a2^2 - b2^2 +....+ an^2 - bn^2)

 x1*(a1-b1) + x2*(a2-b2) +... + xn*(an-bn) = (a1^2-b1^2 + a2^2-b2^2 +....+ an^2-bn^2)/2     

===========================我是理想与现实分界线_(:з」∠)_============================

我们拥有(n+1)个点的坐标,最后可以化为n个线性方程,

那么我们就拥有了一个线性方程组,n个未知数n个方程且数据保证有解,高斯消元即可

var
    n                   :longint;
    tt                  :double;
    tmp1,tmp2           :array[0..15] of double;
    ans                 :array[0..15] of double;
    a                   :array[0..15,0..15] of double;
    i,j                 :longint;
procedure guass;
var
    i,j,k:longint;
    m:longint;
begin
   for i:=1 to n-1 do
   begin
      m:=i;
      for j:=i+1 to n do
        if abs(a[j,i])>abs(a[m,i]) then m:=j;
      if (m<>i) then
      begin
         tmp1:=a[j];a[j]:=a[i];a[i]:=tmp1;
      end;
      if a[i,i]=0 then continue;
      for j:=i+1 to n do
      begin
         tt:=a[j,i]/a[i,i];
         a[j,i]:=0;
         for k:=i+1 to n+1 do a[j,k]:=a[j,k]-tt*a[i,k];
      end;
   end;
   //
   ans[n]:=a[n,n+1]/a[n,n];
   for i:=n-1 downto 1 do
   begin
      tt:=0;
      for j:=i+1 to n do tt:=tt+ans[j]*a[i,j];
      ans[i]:=(a[i,n+1]-tt)/a[i,i];
   end;
end;

begin
   read(n);
   for j:=1 to n do read(tmp1[j]);
   for j:=1 to n do read(tmp2[j]);
   for j:=1 to n do
   begin
      a[1,j]:=tmp1[j]-tmp2[j];
      a[1,n+1]:=a[1,n+1]+(tmp1[j]*tmp1[j]-tmp2[j]*tmp2[j])/2;
   end;
   for i:=3 to n+1 do
   begin
      tmp1:=tmp2;
      for j:=1 to n do read(tmp2[j]);
      for j:=1 to n do
      begin
         a[i-1,j]:=tmp1[j]-tmp2[j];
         a[i-1,n+1]:=a[i-1,n+1]+(tmp1[j]*tmp1[j]-tmp2[j]*tmp2[j])/2;
      end;
   end;
   //
   guass;
   for i:=1 to n-1 do write(ans[i]:0:3,' ');writeln(ans[n]:0:3);
end.
——by Eirlys
bzoj 1013 高斯消元_第1张图片


你可能感兴趣的:(bzoj,模板,guass)