高斯消元 hihoCoder1195 高斯消元·一

传送门:点击打开链接

思路:高斯消元。。

没学线代前看了好久的高斯消元都没看懂,感觉线代书里的高斯消元讲的详细多了。。

然后网上找过关于高斯消元的代码,几乎没有能返回是否有解,有几组解等的代码-_-

然后今天写了一天,也总算完成了

大概的思路也就是做出梯形矩阵,然后判断矩阵的秩,详细推荐参考线性代数的书会比较好

如果不想弄懂也行,,反正模板已弄好了,以后可以直接套模板

下面是模板

const double exps = 1e-8;
typedef vector<double> vec;
typedef vector<vec> mat;

int dcmp(double x) {
    if(fabs(x) < exps) return 0;
    return x < 0 ? -1 : 1;
}

void guass(mat &A, int m, int n) {
    for(int i = 0; i < m; i++) {
        int pv = i, id;
        for(int j = 0; j <= n; j++) {
            for(int k = i + 1; k < m; k++) {
                if(fabs(A[k][j]) > fabs(A[pv][j])) {
                    pv = k;
                }
            }
            if(dcmp(A[pv][j])) break;
        }
        swap(A[i], A[pv]);

        for(id = 0; id <= n && !dcmp(A[i][id]); id++);
        if(id > n) return;

        for(int j = i + 1; j < m; j++) {
            if(!dcmp(A[j][id])) continue;

            double f = A[j][id] / A[i][id];
            for(int k = id + 1; k <= n; k++) A[j][k] -= A[i][k] * f;
            A[j][id] = 0;
        }
    }
}

/*
A是增广矩阵
n表示未知数个数,下标从0开始,下标n中的表示等号右边
-1表示无解,0表示多组解,1表示唯一一组解
如果是唯一解,会保存在A[i][n]中
*/
int solve(mat &A) {
    int m = A.size(), n = A[0].size() - 1;
    guass(A, m, n);

    int r1 = 0, r2 = 0;
    for(int i = 0; i < m; i++) {
        bool sign = true;
        for(int j = 0; j <= n; j++) {
            if(dcmp(A[i][j])) {
                r2++;
                if(j < n) r1++;
                sign = false;
                break;
            }
        }
        if(sign) break;
    }

    if(r1 != r2) return -1;
    if(r1 == r2 && r1 != n) return 0;
    for(int i = n - 1; i >= 0; i--) {
        A[i][n] /= A[i][i];
        for(int j = i - 1; j >= 0; j--) A[j][n] -= A[i][n] * A[j][i];
    }
    return 1;
}

无脑式模板不解释→_→


然后用上面这个模板套了下这道模板题

#include<map>
#include<set>
#include<cmath>
#include<stack>
#include<queue>
#include<cstdio>
#include<cctype>
#include<string>
#include<vector>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<functional>
#define fuck printf("fuck")
#define FIN freopen("input.txt","r",stdin)
#define FOUT freopen("output.txt","w+",stdout)
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;

const int MX = 3e5 + 5;
const double exps = 1e-8;
typedef vector<double> vec;
typedef vector<vec> mat;

int dcmp(double x) {
    if(fabs(x) < exps) return 0;
    return x < 0 ? -1 : 1;
}

int to_int(double x) {
    return round(x);
}

void guass(mat &A, int m, int n) {
    for(int i = 0; i < m; i++) {
        int pv = i, id;
        for(int j = 0; j <= n; j++) {
            for(int k = i + 1; k < m; k++) {
                if(fabs(A[k][j]) > fabs(A[pv][j])) {
                    pv = k;
                }
            }
            if(dcmp(A[pv][j])) break;
        }
        swap(A[i], A[pv]);

        for(id = 0; id <= n && !dcmp(A[i][id]); id++);
        if(id > n) return;

        for(int j = i + 1; j < m; j++) {
            if(!dcmp(A[j][id])) continue;

            double f = A[j][id] / A[i][id];
            for(int k = id + 1; k <= n; k++) A[j][k] -= A[i][k] * f;
            A[j][id] = 0;
        }
    }
}

/*
A是增广矩阵
n表示未知数个数,下标从0开始,下标n中的表示等号右边
-1表示无解,0表示多组解,1表示唯一一组解
如果是唯一解,会保存在A[i][n]中
*/
int solve(mat &A) {
    int m = A.size(), n = A[0].size() - 1;
    guass(A, m, n);

    int r1 = 0, r2 = 0;
    for(int i = 0; i < m; i++) {
        bool sign = true;
        for(int j = 0; j <= n; j++) {
            if(dcmp(A[i][j])) {
                r2++;
                if(j < n) r1++;
                sign = false;
                break;
            }
        }
        if(sign) break;
    }

    if(r1 != r2) return -1;
    if(r1 == r2 && r1 != n) return 0;
    for(int i = n - 1; i >= 0; i--) {
        A[i][n] /= A[i][i];
        for(int j = i - 1; j >= 0; j--) A[j][n] -= A[i][n] * A[j][i];
    }
    return 1;
}

int main() {
    int n, m; //FIN;
    while(~scanf("%d%d", &n, &m)) {
        mat A(m, vec(n + 1));
        for(int i = 0; i < m; i++) {
            for(int j = 0; j <= n; j++) {
                scanf("%lf", &A[i][j]);
            }
        }
        int ret = solve(A);
        if(ret < 0) printf("No solutions\n");
        else if(ret == 0) printf("Many solutions\n");
        else for(int i = 0; i < n; i++) {
                printf("%d\n", to_int(A[i][n]));
            }
    }
    return 0;
}


你可能感兴趣的:(高斯消元 hihoCoder1195 高斯消元·一)