高斯消元模板及应用

用途:求线性方程组的解

解的个数

  1. 完美阶梯型——唯一解
  2. 0=非零——无解
  3. 存在0=0——无穷多解

时间复杂度:O\left ( n^{3} \right )

步骤:

模板:

【模板】高斯消元法 - 洛谷

code:

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const int maxn=110;
const double eps=1e-6;
int n;
double a[maxn][maxn];

int gauss(){
    //枚举列
    int r,c;
    for(r=1,c=1;c<=n;c++){
        //找主元
        int id=r;
        for(int i=r;i<=n;i++){
            if(fabs(a[i][c])>fabs(a[id][c])){
                id=i;
            }
        }
        if(fabs(a[id][c])<eps)
            continue;
        //交换
        for(int i=c;i<=n+1;i++){
            swap(a[r][i],a[id][i]);
        }
        //归一
        for(int i=n+1;i>=c;i--){
            a[r][i]/=a[r][c];
        }
        //消
        for(int i=r+1;i<=n;i++){
            if(fabs(a[i][c])>eps){
                for(int j=n+1;j>=c;j--){
                    a[i][j]-=a[r][j]*a[i][c];
                }
            }
        }
        r++;
    }
    //判断解的个数
    if(r<=n){
        return 1;
    }
    //按列消成对角矩阵
    for(int i=n;i>=1;i--){
        for(int j=i+1;j<=n;j++){
            a[i][n+1]-=a[i][j]*a[j][n+1];
        }
    }
    return 0;
}

int main(){
//    freopen("123.in","r",stdin);
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n+1;j++){
            scanf("%lf",&a[i][j]);
        }
    }
    int t=gauss();
    if(t==0){
        for (int i = 1; i <= n; i ++ ){
            if (fabs(a[i][n]) < eps) a[i][n] = 0;
            printf("%.2lf\n", a[i][n+1]);
        }
    }
    else{
        puts("No Solution");
    }
    return 0;
}

应用一:

 高斯消元解线性方程组

思路:此题只加了对解的个数的判断

code:

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const int maxn=110;
const double eps=1e-6;
int n;
double a[maxn][maxn];

int gauss(){
    //枚举列
    int r,c;
    for(r=1,c=1;c<=n;c++){
        //找主元
        int id=r;
        for(int i=r;i<=n;i++){
            if(fabs(a[i][c])>fabs(a[id][c])){
                id=i;
            }
        }
        if(fabs(a[id][c])<eps)
            continue;
        //交换
        for(int i=c;i<=n+1;i++){
            swap(a[r][i],a[id][i]);
        }
        //归一
        for(int i=n+1;i>=c;i--){
            a[r][i]/=a[r][c];
        }
        //消
        for(int i=r+1;i<=n;i++){
            if(fabs(a[i][c])>eps){
                for(int j=n+1;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+1])>eps){
                return 2;
            }
            return 1;
        }
    }
    //按行消成对角矩阵
    for(int i=n;i>=1;i--){
        for(int j=i+1;j<=n;j++){
            a[i][n+1]-=a[i][j]*a[j][n+1];
        }
    }
    return 0;
}

int main(){
//    freopen("123.in","r",stdin);
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n+1;j++){
            scanf("%lf",&a[i][j]);
        }
    }
    int t = gauss();

    if (t == 0)
    {
        for (int i = 1; i <= n; i ++ ){
            if (fabs(a[i][n+1]) < eps) a[i][n+1] = 0;
            printf("%.2lf\n", a[i][n+1]);
        }
    }
    else if (t == 1) puts("Infinite group solutions");
    else puts("No solution");
    return 0;
}

应用二:

高斯消元异或线性方程组AcWing

思路:异或<=>不进位的加法

code:

#include "bits/stdc++.h"
using namespace std;
typedef long long ll;
const int maxn=110;
int n,a[maxn][maxn];

int gauss(){
    //枚举列
    int r,c;
    for(r=1,c=1;c<=n;c++){
        //找主元
        int id=r;
        for(int i=r;i<=n;i++){
            if(a[i][c]){
                id=i;
                break;
            }
        }
        if(!a[id][c])
            continue;
        //交换
        for(int i=c;i<=n+1;i++){
            swap(a[r][i],a[id][i]);
        }
        //消
        for(int i=r+1;i<=n;i++){
            if(a[i][c]){
                for(int j=n+1;j>=c;j--){
                    a[i][j]^=a[r][j];
                }
            }
        }
        r++;
    }
    //判断解的个数
    if(r<=n){
        for(int i=r;i<=n;i++){
            if(a[i][n+1])
                return 2;
        }
        return 1;
    }
    //按行消成对角矩阵
    for(int i=n;i>=1;i--){
        for(int j=i+1;j<=n;j++){
            a[i][n+1]^=a[i][j]&a[j][n+1];
        }
    }
    return 0;
}

int main(){
//    freopen("123.in","r",stdin);
    scanf("%d",&n);
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n+1;j++){
            scanf("%d",&a[i][j]);
        }
    }
    int op=gauss();
    if(op==0){
        for(int i=1;i<=n;i++){
            printf("%d\n",a[i][n+1]);
        }
    }
    else if(op==1) printf("Multiple sets of solutions\n");
    else printf("No solution\n");
    return 0;
}

应用三:

[JSOI2008]球形空间产生器 - 洛谷

思路:

code:

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值