时间限制 内存限制
1000 ms 65536 KB

# 题目描述

给定一个含有 nn 个方程的 nn 元线性方程组(保证方程组有唯一解),求出这组解。

# 输入

第一行一个正整数 tt,表示数据组数,1t501 \le t \le 50

对于每组数据,第一行一个正整数 nn 代表未知数与方程的个数,2n1002 \le n \le 100

接下来 nn 行,每行 n+1n + 1 个数字,表示方程组的增广矩阵。对于系数,保证 10Ai,j10−10 \le A_{i, j} \le 10。对于常数列,保证 100bi100−100 \le b_i \le 100

数据保证,方程组有且仅有唯一解,且 1xi10xiZ1 \le |x_i| \le 10,x_i \in \Z,即 xix_i10−101−1 之间或 111010 之间的整数。

数据保证,化简增广矩阵的过程不会超过 double 的精度范围。

# 输出

对于每组数据,输出一行 nn 个整数,代表方程组的解。

# 输入样例

3
2
-1 1 4
5 -1 4
3
1 1 0 0
1 0 1 3
0 1 1 1
4
1 1 1 1 2
2 2 -1 2 13
-4 -2 1 1 1
5 7 -3 -4 2

# 输出样例

2 6
1 -1 2
-1 2 -3 4

# 题解:高斯消元

高斯消元简化板子题,不会做的滚去重修线代😈😈😈

参考代码:

#include <stdio.h>
#include <math.h>
#define eps 1e-6
int n;
double mat[105][105];
void Swap(double *a, double *b)
{
    double t = *a;
    *a = *b;
    *b = t;
    return;
}
int main()
{
    // freopen("G.in", "r", stdin);
    // freopen("G.out", "w", stdout);
    int T;
    scanf("%d", &T);
    while (T -- )
    {
        scanf("%d", &n);
        for (int i = 1; i <= n; ++ i)
            for (int j = 1; j <= n + 1; ++ j)
                scanf("%lf", &mat[i][j]);
        
        for (int i = 1; i <= n; ++ i)
        {
            int line = i;
            while (line <= n && fabs(mat[line][i]) < eps)
                ++ line;
            
            for (int j = i; j <= n + 1; ++ j)
                Swap(&mat[i][j], &mat[line][j]);
            
            for (int j = i + 1; j <= n; ++ j)
            {
                double k = -mat[j][i] / mat[i][i];
                for (int p = i; p <= n + 1; ++ p)
                    mat[j][p] += k * mat[i][p];
            }
        }
        for (int i = n; i >= 1; -- i)
            for (int j = i - 1; j >= 1; -- j)
            {
                double k = -mat[j][i] / mat[i][i];
                for (int p = i; p <= n + 1; ++ p)
                    mat[j][p] += k * mat[i][p];
            }
        
        for (int i = 1; i <= n; ++ i)
            printf("%.0lf ", mat[i][n + 1] / mat[i][i]);
        
        puts("");
    }
    return 0;
}