の形
\(\開始{ケース} A_ {11} X_ {1} + A_ {12} X_ {2} + ... + A_ {1N} X_ {N} = B_ {1} \\ A_ {21 } X_ {1} + A_ {22} X_ {2} + ...... + A_ {2N} X_ {N} = B_ {2} \\ ...... A_ {N1} X_ {1 } + A_ {N2} X_ {2} + ... + A_ {NN} X_ {N} = B_ {N} \端{ケース} \)
上記の式:
\(A = \)\(\開始{bmatrix} A_ {11} - \ cdots&A_ {1N} \\ \ vdots&\ vdots&\ vdots \\ A_ {N1}&\ cdots&A_ {NN} \端{bmatrix} \)
\(B = \)\(\開始{bmatrix} B_ {1} \\ \ vdots \\ B_ {N} \端{bmatrix} \)
\(X = \)\(\開始{bmatrix} X_ {1} \\ \ vdots \\ X_ {N} \端{bmatrix} \)
見ることができます:\(AX = B \)
第二に、基本変換(行)
1.同じまたは他の(非ゼロ)の数とラインによって
別の行に2行
3.任意の二つの行の交換
値は(私たちは皆知っている)と同じです
第三に、ステップ
私たちは、一次方程式の解は同等の基本方程式である見つけることができますので、我々はステップ小学校をシミュレートするために、方程式法と同等です
1.撤廃
最初に私たちが考えるために\(私は\)の方程式、我々は排除排除\を(X_ {I} \)
だから我々は見つかり各方程式を見つける必要がある\(X_I \)最大の係数\(MAXN \)それは最初、およびそれに対応する式を(私は\)\スワップを方程式、これは最大の係数を確保することができます\ (X_I \)の治療の最小数、最小時間。
最大の要因を見つけた後、私たちは何を決定する必要があります\(MAXN \)が 0に等しいが、何の解決策を示していない場合は、0に等しいです。使用しかし、\(ダブル\) 、型は精度の問題を検討するために、条件はよりも小さいと判定された\(EPS \) 、
for(int i=1;i<=n;i++)
{
int now=i;
for(int j=i+1;j<=n;j++)
{
if(fabs(a[now][i])<fabs(a[j][i]))now=j;//寻找x[i]的最大系数
}
if(fabs(a[now][i])<eps)//判断,如果x[i]的系数小于eps,说明x[i]=0,判断为无解
{
puts("No Solution");
return 0;
}
if(i!=now)swap(a[i],a[now]);//将最大系数x[i]所在的方程与第i方程交换
私たちは、作られました小学校数学オリンピック可用性、我々が作るのであれば、\(X_I \)が消え、最も便利な方法は、すべての方程式を置くことです\(X_I \)への係数の\(1 \) 、その後、あなたは排除を加算および減算することができ、中式中の他のプロセス変数がそれに応じて変更されることに注意してください
dl div=a[i][i];//这就是maxn
for(int j=i;j<=n+1;j++)a[i][j]/=div;//先处理以maxn为系数的x[i]所在的方程
for(int j=i+1;j<=n;j++)//将其他方程都进行处理
{
div=a[j][i];//其他方程的x[i]的系数
for(int k=i;k<=n+1;k++)
{
a[j][k]-=div*a[i][k];
}
}
}
私たちはこのループをやり続けることができるように、最終的な処理\(X_N \)
ans[n]=a[n][n+1]/a[n][n];
2.バック代入
後退代入もよく、より都度理解される\(\ N-)アナログ代入式に戻って、それぞれの処理\(X_I \)
for(int i=n-1;i>=1;i--)
{
ans[i]=a[i][n+1];
for(int j=i+1;j<=n;j++)ans[i]-=ans[j]*a[i][j];
}
全体のコード
#include<bits/stdc++.h>
using namespace std;
typedef double dl;
const int N=110;
const dl eps=1e-9;
dl a[N][N],ans[N],x[N][N];
int n;
int main()
{
scanf("%d",&n);
for(int i=1;i<=n+1;i++)
{
for(int j=1;j<=n;j++)
{
scanf("%lf",&x[i][j]);
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=n;j++)
{
a[i][j]=2*(x[1][j]-x[i+1][j]);
a[i][n+1]+=x[1][j]*x[1][j]-x[i+1][j]*x[i+1][j];
}
}
for(int i=1;i<=n;i++)
{
int now=i;
for(int j=i+1;j<=n;j++)
{
if(fabs(a[now][i])<fabs(a[j][i]))now=j;
}
if(fabs(a[now][i])<eps)
{
puts("No Solution");
return 0;
}
if(i!=now)swap(a[i],a[now]);
dl div=a[i][i];
for(int j=i;j<=n+1;j++)a[i][j]/=div;
for(int j=i+1;j<=n;j++)
{
div=a[j][i];
for(int k=i;k<=n+1;k++)
{
a[j][k]-=div*a[i][k];
}
}
}
ans[n]=a[n][n+1]/a[n][n];
for(int i=n-1;i>=1;i--)
{
ans[i]=a[i][n+1];
for(int j=i+1;j<=n;j++)ans[i]-=ans[j]*a[i][j];
}
for(int i=1;i<=n;i++)printf("%.3lf ",ans[i]);
return 0;
}
第四に、解決策を決定
\(A、一意の解を有する:\)最後のアウト処理\(X_I \)係数が0ではなく、プロセスは係数0を派生されていません
\(B、無溶液:\)そのプロセスのために見出さ\(X_I \)\(MAXN = 0 \)
\(C、無限のソリューション:\)最後のアウト処理\(X_I \)の係数が0であり、式の右辺も0であります
タイトル:
P3389 [テンプレート]ガウスの消去
P2455 [SDOI2006]線形方程式
V.の概要
実際には、あなたがよく理解されているガウスの消去法を見つけることができ、主な困難は、線形方程式を導出する方法の工程の前にある、テンプレートのセットのような後に直接導出