更 好 的 观 赏 体 验 \large 更好的观赏体验 更好的观赏体验
原题链接
题目大意
给定一个线性方程组,对其求解。
Example
Explain
\texttt{Example Explain}
Example Explain
样例所示的方程组为:
{
x
+
3
y
+
4
z
=
5
(
1
)
x
+
4
y
+
7
z
=
3
(
2
)
9
x
+
3
y
+
2
z
=
2
(
3
)
\begin{cases} x+3y+4z=5&(1)\\ x+4y+7z=3&(2)\\ 9x+3y+2z=2&(3)\\ \end{cases}
⎩⎪⎨⎪⎧x+3y+4z=5x+4y+7z=39x+3y+2z=2(1)(2)(3)
解题思路
高斯消元法的基本解题思路就是把其中的一个未知数先 系数化为一,然后再用这个未知数 消掉其他方程内的这个未知数,最后得出结果。
没看懂?用样例来解释一下。
首先把 x x x 系数化为一, ( 1 ) (1) (1) 方程已经做到了。
然后用
(
2
)
−
(
1
)
(2)-(1)
(2)−(1),把
(
2
)
(2)
(2) 中的
x
x
x 消掉,再用
(
3
)
−
9
×
(
1
)
(3)-9\times (1)
(3)−9×(1),把
(
3
)
(3)
(3) 中的
x
x
x 消掉,最后方程式变成:
{
x
+
3
y
+
4
z
=
5
(
1
)
y
+
3
z
=
−
2
(
2
)
−
24
y
−
34
z
=
−
43
(
3
)
\begin{cases} x+3y+4z=5&(1)\\ y+3z=-2&(2)\\ -24y-34z=-43&(3)\\ \end{cases}
⎩⎪⎨⎪⎧x+3y+4z=5y+3z=−2−24y−34z=−43(1)(2)(3)
然后再把 y y y 系数化为一,此时就不能用到上面的 ( 1 ) (1) (1) 了,因为会导致 x x x 的出现。而这个工作也已经完成了。
然后用
(
1
)
−
3
×
(
2
)
,
(
3
)
−
(
−
24
)
×
(
2
)
(1)-3\times (2)\ ,\ (3)-(-24)\times(2)
(1)−3×(2) , (3)−(−24)×(2) 得到:
{
x
−
5
z
=
11
(
1
)
y
+
3
z
=
−
2
(
2
)
38
z
=
−
91
(
3
)
\begin{cases} x-5z=11&(1)\\ y+3z=-2&(2)\\ 38z=-91&(3)\\ \end{cases}
⎩⎪⎨⎪⎧x−5z=11y+3z=−238z=−91(1)(2)(3)
最后,就是解最后一个
z
z
z 了。首先,系数化为一,
(
3
)
(3)
(3) 变为
z
=
−
91
38
z=-\frac{91}{38}
z=−3891,然后再把其他两个方程中的
z
z
z 去掉,变为:
{
x
=
−
37
38
(
1
)
y
=
197
38
(
2
)
z
=
−
91
38
(
3
)
\begin{cases} x=-\frac{37}{38}&(1)\\[3pt] y=\frac{197}{38}&(2)\\[3pt] z=-\frac{91}{38}&(3)\\ \end{cases}
⎩⎪⎪⎨⎪⎪⎧x=−3837y=38197z=−3891(1)(2)(3)
保留两位小数后就是:
{
x
=
−
0.97
(
1
)
y
=
5.18
(
2
)
z
=
−
2.39
(
3
)
\begin{cases} x=-0.97&(1)\\ y=5.18&(2)\\ z=-2.39&(3)\\ \end{cases}
⎩⎪⎨⎪⎧x=−0.97y=5.18z=−2.39(1)(2)(3)
和样例一样。
随后,就可以把这个推出有 n n n 个方程的结果。
而有多数解只有一种可能,就是该方程中没有此未知数,即未知数为 0 0 0。
上代码
#include<bits/stdc++.h>
#define endl '\n'
using namespace std;
double a[110][110];
int n;
void print2DMatrix()
{
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n+1; j++)
printf("%0.2lf ",a[i][j]);
printf("\n");
}
printf("\n");
return;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
/* Code */
cin>>n;
for(int i=1; i<=n; i++)
for(int j=1; j<=n+1; j++)
cin>>a[i][j];
for(int i=1; i<=n; i++)
{
int maxpos=i;
for(int j=i+1; j<=n; j++)
if(a[j][i]>a[maxpos][i])
maxpos=j;
for(int j=1; j<=n+1; j++)
swap(a[i][j],a[maxpos][j]);
// print2DMatrix();
double temp=a[i][i];
if(temp==0)
{
cout<<"No Solution"<<endl;
return 0;
}
for(int j=1; j<=n+1; j++)
a[i][j]/=temp;
for(int j=1; j<=n; j++)
{
if(j==i)
continue;
temp=a[j][i];
for(int k=1; k<=n+1; k++)
a[j][k]-=temp*a[i][k];
}
// print2DMatrix();
}
for(int i=1; i<=n; i++)
printf("%0.2lf\n",a[i][n+1]);
return 0;
}