题目描述
输入一个包含n个方程n个未知数的线性方程组。
方程组中的系数为实数。
求解这个方程组。
下图为一个包含m个方程n个未知数的线性方程组示例:
输入格式
第一行包含整数n。
接下来n行,每行包含n+1个实数,表示一个方程的n个系数以及等号右侧的常数。
输出格式
如果给定线性方程组存在唯一解,则输出共n行,其中第i行输出第i个未知数的解,结果保留两位小数。
如果给定线性方程组存在无数解,则输出“Infinite group solutions”。
如果给定线性方程组无解,则输出“No solution”。
数据范围
1≤n≤100,
所有输入系数以及常数均保留两位小数,绝对值均不超过100。
输入样例:
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
主要考点
C ++ 代码
#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
using namespace std;
const int N = 110;
const double eps = 1e-7;
double a[N][N];//增广矩阵
int n;
int gauss(){
int r, c;
//枚举列
for(c = 0, r = 0; c < n; c ++){
//找到当前列以下所有行的最大值的行号
int t = r;
for(int i = r; i < n; i ++){
if(fabs(a[i][c]) > fabs(a[t][c])) t = i;
}
//剩余当前列最大行的元素为0,则已满足要求,直接跳过即可
if(fabs(a[t][c]) < eps) continue;
//当最大行的元素交换到剩余行的行首
for(int i = c; i <= n; i ++){
if(t == r) continue;
swap(a[r][i], a[t][i]);
}
//处理剩余行首(最大行)的各元素,使得当前列的元素为1
for(int i = n; i >= c; i --){
a[r][i] /= a[r][c];
}
//处理当前列剩余最大行以下的所有元素,使其均为0
for(int i = r + 1; i < n; i ++){
if(fabs(a[i][c]) < eps) continue;
for(int j = n; j >= c; j --){
a[i][j] -= a[r][j] * a[i][c];
}
}
r ++;//以保证当前行以上均为上三角矩阵,且非零首元均为1, 处理下一行
}
//存在全0行(等号左边全为0)
if(r < n){
for(int i = r; i < n; i ++){
if(fabs(a[i][n]) > eps) return 0;//出现等号左侧为0,右侧不为0的情况,即无解
}
return 2;//有无穷多解
}
//由最后一行倒退至第一行求地未知数的解
for(int i = n - 1; i >= 0; i --){
for(int j = i + 1; j < n; j ++){//i + 1表示当前未知数x后的所有已知解得未知数的起始位置
a[i][n] -= a[i][j] * a[j][n];//用增广矩阵所在列元素存放未知数的值
}
}
return 1;//有唯一解
}
int main(){
cin >> n;
for(int i = 0; i < n; i ++){
for(int j = 0; j < n + 1; j ++){
cin >> a[i][j];
}
}
int t = gauss();
if(t == 1){
for(int i = 0; i < n; i ++){
printf("%.2lf\n", a[i][n]);
}
}
if(t == 0) printf("No solution");
if(t == 2) printf("Infinite group solutions");
return 0;
}