输入一个包含 nn 个方程 nn 个未知数的线性方程组。
方程组中的系数为实数。
求解这个方程组。
下图为一个包含 mm 个方程 nn 个未知数的线性方程组示例:
输入格式
第一行包含整数 nn。
接下来 nn 行,每行包含 n+1n+1 个实数,表示一个方程的 nn 个系数以及等号右侧的常数。
输出格式
如果给定线性方程组存在唯一解,则输出共 nn 行,其中第 ii 行输出第 ii 个未知数的解,结果保留两位小数。
如果给定线性方程组存在无数解,则输出
Infinite group solutions
。如果给定线性方程组无解,则输出
No solution
。数据范围
1≤n≤1001≤n≤100,
所有输入系数以及常数均保留两位小数,绝对值均不超过 100100。输入样例:
3 1.00 2.00 -1.00 -6.00 2.00 1.00 -3.00 -9.00 -1.00 -1.00 2.00 7.00
输出样例:
1.00 -2.00 3.00
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
using namespace std;
const int N=110;
const double eps=1e-6;
double a[N][N];
int n;
int gauss()
{
int c,r;
for(c=1,r=1; c<=n; c++)
{
int t=r;
for(int i=r; i<=n; i++) //1 寻找
{
if(fabs(a[i][c])>fabs(a[t][c])) t=i;
}
if(fabs(a[t][c])<eps) continue;
for(int i=c; i<=n+1; i++) swap(a[r][i],a[t][i]); //2 交换
for(int i=n+1; i>=c; i--) a[r][i]=a[r][i]/a[r][c]; //3 化简
for(int i=r+1; i<=n; i++) //将该行下面的该列都清零
{
if (fabs(a[i][c]) > eps)//如果当前列不为0,为0的话就不用清了了。
for(int j=n+1; j>=c; j--)
{
a[i][j]-=a[i][c]*a[r][j];
}
}
r++;
}
if (r <= n)//说明我们的 第r到 第n行都是全零。
{
for (int i = r; i <= n; i ++ )//如果常数项不为零就会产生 0 = 3 这种矛盾
if (fabs(a[i][n+1]) > eps)
return 2;//无解
return 1;
}
for (int i = n; i >=1; i -- )//倒着推解
for (int j = i + 1; j <= n; j ++ )
a[i][n+1] -= a[j][n+1] * a[i][j];
return 0;
}
int main(void)
{
cin>>n;
for(int i=1; i<=n; i++)
{
for(int j=1; j<=n+1; j++)
cin>>a[i][j];
}
int t=gauss();
if (t == 0)
{
for (int i = 1; i <= n; i ++ )
{
if(abs(a[i][n+1])<eps)
{
printf("0.00\n");
}
else
printf("%.2lf\n", a[i][n+1]);
}
}
else if (t == 1) puts("Infinite group solutions");
else puts("No solution");
return 0;
}