洛谷题单指南-基础线性代数-P2455 [SDOI2006] 线性方程组

原题链接:https://www.luogu.com.cn/problem/P2455

题意解读:求解n元线性一次方程组。

解题思路:

高斯消元是求解n元线性一次方程组的经典算法,主要过程如下:

1、增广矩阵

首先,将方程组的所有系数和值提取出来,构成一个n * (n + 1)的增广矩阵。

image

2、行列变换

对矩阵进行如下行列变换,可以保证对应的方程组的解不变。

  • 交换两行:比如把第 1 行和第 3 行交换,只是调整方程顺序;相当于交换1/3两行方程。
  • 某一行乘以非零常数:比如第 1 行全乘 1/2,方程等价;相当于第一行方程乘以1/2。
  • 某一行的 k 倍加到另一行:比如第 1 行 ×3 加到第 2 行,消去第 2 行的 x 项;相当于将第1行方程×3 加到第 2 行方程。

3、消元过程

高斯消元的目标是要通过行列变换,将矩阵变成对角线矩阵,也就是除了对角线和第n+1列,其余都是0。

image

实现过程如下:

从第1行开始,设开始行row

遍历每列,设当前列col

  找到该列值最大的行,与开始行交换(如果最大列植是0,则直接跳过,处理下一个列)

  将row行col列变成1,也就是该行都除以a[row][col]

  将除row行以外的行col列变成0,也就是都减去row行乘以a[其余行][col] 

  row行处理完毕,row++

4、解的判断

如果在三角系数中

所有系数都不为0,则有唯一解。

如果系数都是0,值也是0,即0=0的情况,有无穷多解。

如果系数都是0,值不为0,即0=非0的情况,无解。

100分代码:

#include <bits/stdc++.h>
using namespace std;

const int N = 55;
const double EPS = 1e-6;
double a[N][N];
int n;

int gauss()
{
    int row = 1; //当前行
    for(int col = 1; col <= n; col++) //枚举当前列
    {
        int t = row;
        for(int i = row + 1; i <= n; i++) //找到当前列绝对值最大的行,目的是为了避免溢出,因为将最大的数变为1后,再做乘法溢出的风险会大大降低
            if(fabs(a[i][col]) > fabs(a[t][col]))
                t = i;
        if(fabs(a[t][col]) < EPS) continue; //如果当前列绝对值最大的行是0,则继续枚举下一列
        for(int i = col; i <= n + 1; i++) swap(a[t][i], a[row][i]); //将当前列绝对值最大的行与当前行交换
        for(int i = n + 1; i >= col; i--) a[row][i] /= a[row][col]; //将当前行当前列的元素变为1
        for(int i = 1; i <= n; i++) //将当前列的其它行消成0
        {
            if(i == row) continue; 
            for(int j = n + 1; j >= col; j--) 
                a[i][j] -= a[row][j] * a[i][col];
        }
        row++; //继续下一行
    }
    if(row <= n)
    {
        for(int i = row; i <= n; i++)
            if(fabs(a[i][n + 1]) > EPS) //无解
                return -1;
        return 0; //无穷多解
    }
    return 1; //唯一解
}

int main()
{
    cin >> n;
    for(int i = 1; i <= n; i++)
        for(int j = 1; j <= n + 1; j++)
            cin >> a[i][j];
    
    int res = gauss();
    if(res == 1)
    {
        for(int i = 1; i <= n; i++)
        {
            printf("x%d=%.2lf\n", i, a[i][n + 1]);
        }
    }
    else cout << res;
    return 0;
}

 

posted @ 2026-02-24 16:00  hackerchef  阅读(0)  评论(0)    收藏  举报