题面描述
有 n n n个未知数 x 1 x_1 x1, x 2 x_2 x2, x 3 x_3 x3…… x n x_n xn,满足:
a
1
,
1
∗
x
1
+
a
1
,
2
∗
x
2
+
a
1
,
3
∗
x
3
…
…
+
a
1
,
n
∗
x
n
=
b
1
a_{1,1}*x_1+a_{1,2}*x_2+a_{1,3}*x_3……+a_{1,n}*x_n=b_1
a1,1∗x1+a1,2∗x2+a1,3∗x3……+a1,n∗xn=b1
a
2
,
1
∗
x
1
+
a
2
,
2
∗
x
2
+
a
2
,
3
∗
x
3
…
…
+
a
2
,
n
∗
x
n
=
b
2
a_{2,1}*x_1+a_{2,2}*x_2+a_{2,3}*x_3……+a_{2,n}*x_n=b_2
a2,1∗x1+a2,2∗x2+a2,3∗x3……+a2,n∗xn=b2
…
…
…
…
…
…
…
…
…
…
…
…
…
…
……………………………………
……………………………………
a
n
,
1
∗
x
1
+
a
n
,
2
∗
x
2
+
a
n
,
3
∗
x
3
…
…
+
a
n
,
n
∗
x
n
=
b
n
a_{n,1}*x_1+a_{n,2}*x_2+a_{n,3}*x_3……+a_{n,n}*x_n=b_n
an,1∗x1+an,2∗x2+an,3∗x3……+an,n∗xn=bn
求
x
1
,
x
2
,
x
3
…
…
x
n
x_1,x_2,x_3……x_n
x1,x2,x3……xn的值。(保证有解)
【输入格式】
第一行给出
n
(
1
<
=
n
<
=
100
)
n(1<=n<=100)
n(1<=n<=100)
下来
n
n
n行,每行给出
n
+
1
n+1
n+1个实数,分别是
a
i
,
1
a_{i,1}
ai,1~
a
i
,
n
a_{i,n}
ai,n 和
b
i
b_i
bi。
【输出格式】
输出
x
1
,
x
2
,
x
3
…
…
x
n
x_1,x_2,x_3……x_n
x1,x2,x3……xn的值(相邻两个用一个空格隔开,每个数保留
3
3
3位小数)
【样例输入】
3
2.5 5.0 3.0 32.5
1.0 4.5 2.0 22
4.0 3.5 1.5 26.5
【样例输出】
3.000 2.000 5.000
思路
作为高斯消元法的模版题,主要有两种初中的消元方法,分别是加减消元,以及代入消元。
实际步骤:
如图,
∣
2.5
5.0
3.0
∣
32.5
1.0
4.5
2.0
∣
22
4.0
3.5
1.5
∣
26.5
∣
\begin{vmatrix} 2.5&5.0&3.0|&32.5 \\1.0&4.5&2.0|&22 \\4.0&3.5&1.5|&26.5\end{vmatrix}
∣∣∣∣∣∣2.51.04.05.04.53.53.0∣2.0∣1.5∣32.52226.5∣∣∣∣∣∣
⇛
\Rrightarrow
⇛
∣
2.5
5.0
3.0
∣
32.5
0
2.5
0.8
∣
9
0
−
4.5
−
3.3
∣
−
25.5
∣
\begin{vmatrix} 2.5&5.0&3.0|&32.5 \\0&2.5&0.8|&9 \\0&-4.5&-3.3|&-25.5\end{vmatrix}
∣∣∣∣∣∣2.5005.02.5−4.53.0∣0.8∣−3.3∣32.59−25.5∣∣∣∣∣∣
⇛
\Rrightarrow
⇛
∣
2.5
5.0
3.0
∣
32.5
0
2.5
0.8
∣
9
0
0
−
1.86
∣
−
9.3
∣
\begin{vmatrix} 2.5&5.0&3.0|&32.5 \\0&2.5&0.8|&9 \\0&0&-1.86|&-9.3\end{vmatrix}
∣∣∣∣∣∣2.5005.02.503.0∣0.8∣−1.86∣32.59−9.3∣∣∣∣∣∣
⇛
\Rrightarrow
⇛
x
3
=
−
9.3
/
(
−
1.86
)
=
5.000
x_3=-9.3/(-1.86)=5.000
x3=−9.3/(−1.86)=5.000
x
2
=
[
9
−
(
0.8
∗
x
3
)
]
/
2.5
=
2.000
x_2=[9-(0.8*x_3)]/2.5=2.000
x2=[9−(0.8∗x3)]/2.5=2.000
x
1
=
[
32.5
−
15
−
10
]
/
2.5
=
3.000
x_1=[32.5-15-10]/2.5=3.000
x1=[32.5−15−10]/2.5=3.000
- 先从 1 1 1~ n n n枚举每一行,对于 ∀ x , i < x ≤ n \forall x,i<x\le n ∀x,i<x≤n,削去 x x x行 i i i列的系数,使系数成为 0 0 0
- 观察可以发现,最后一行 n n n只有 x n x_n xn的系数不为0,则可求出 x n x_n xn,进而代入消元。
具体过程见代码。
代码
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<cstdlib>
using namespace std;
const int N=110;
double a[N][N];
double f[N];int n;
void gauss()
{
for(int i=1;i<=n;i++)
{
int r=i;//仅仅只是为了减少精度损失
for(int j=i+1;j<=n;j++)if(fabs(a[j][i])>fabs(a[r][i]))r=j;
for(int j=1;j<=n+1;j++){double t=a[r][j];a[r][j]=a[i][j];a[i][j]=t;}
for(int j=n+1;j>=i;j--)
{
for(int k=i+1;k<=n;k++)
a[k][j]-=a[k][i]/a[i][i]*a[i][j];
}
}
for(int i=n;i>=1;i--)
{
double t=a[i][n+1];
for(int j=i+1;j<=n;j++)
{
t-=a[i][j]*f[j];
}
f[i]=t/a[i][i];
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++)for(int j=1;j<=n+1;j++)scanf("%lf",&a[i][j]);
gauss();
for(int i=1;i<=n;i++)printf("%.3lf ",f[i]);puts("");
return 0;
}