Skip to content
Author: lllyouo
Date: 20250709
tag: 高斯消元
link: https://www.luogu.com.cn/problem/P3389

问题描述

link

分析

参考代码

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

const int N = 110;
const double eps = 1e-8;

int n;
double a[N][N];

int gauss() {
    int c, r;
    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;
        }

        if (fabs(a[t][c]) < eps) continue;

        // 交换主元到顶端
        for (int i = c; i <= n; i++) swap(a[t][i], a[r][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) {
                for (int j = n; j >= c; j -- ) {
                    a[i][j] -= a[r][j] * a[i][c];
                }
            }
        }

        r++;
    }

    if (r < n) {
        for (int i = r; i < n; i ++ ) {
            // 无解
            if (fabs(a[i][n]) > eps) return 2;
        }
        
        // 无穷多组解
        return 1; 
    }

    for (int i = n - 1; i >= 0; i--) {
         for (int j = i + 1; j < n; j++) {
            a[i][n] -= a[i][j] * a[j][n];
         }
    }
    
    // 唯一解
    return 0; 
}


int main() {
    scanf("%d", &n);
    for (int i = 0; i < n; i ++ ) {
        for (int j = 0; j < n + 1; j ++ ) {
            scanf("%lf", &a[i][j]);
        }
    }

    int t = gauss();
    if (t == 0) {
        for (int i = 0; i < n; i ++ ) printf("%.2lf\n", a[i][n]);
    } else puts("No Solution"); 

    return 0;
}