【模板】高斯消元

ACM模板


高斯消元解线性方程组

int a[N][N]输入矩阵, n n n行, n + 1 n+1 n+1列,下标从0开始
n + 1 n+1 n+1列表示方程右边的值(n行即n个方程,n列即n个未知数)

int gauss()返回矩阵的秩(矛盾无解返回-1),并且系数矩阵化为单位矩阵
int a[N][N]数组第 n + 1 n+1 n+1列(下标a[i][n])是解 x i x_i xi

时间复杂度: O ( n 3 ) O(n^3) O(n3)

//O(n^3)
#include<bits/stdc++.h>
using namespace std;
const int N=110;
const double eps=1e-6;
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;
        // 该列都为0 则跳过
        if(fabs(a[t][c])<eps) continue;
        // 将该行换到第r行
        for(int i=c;i<=n;i++) swap(a[r][i],a[t][i]);
        // 第r行第一项变成1
        for(int i=n;i>=c;i--) a[r][i]/=a[r][c];

        // 变成上三角 用第r行去消掉其他所有行的第c列
        for(int i=0;i<n;i++)
            if(i!=r&&fabs(a[i][c])>eps) //该行第c列不为0
                for(int j=n;j>=c;j--)
                    a[i][j]-=a[i][c]*a[r][j];
        r++;
    }
    if(r<n) //非完美阶梯型
    {
        for(int i=r;i<n;i++)
            if(a[i][n]>eps) return -1;  // 等式右端不为0
        return r; //返回秩
    }
    return r;
}

异或方程组

n + 1 n+1 n+1列表示方程右边的值(n行即n个方程,n列即n个未知数)
int gauss返回矩阵的秩

时间复杂度: O ( n 3 ) O(n^3) O(n3)

#include<iostream>
using namespace std;
const int N=110;
int n,a[N][N];
int gauss()
{
    int r,c;
    for(c=0,r=0;c<n;c++) //枚举列
    {
        int t=r; //找到不为1的那一行
        for(int i=r;i<n;i++)
            if(a[i][c]) t=i;
        if(!a[t][c]) continue;  //该列都是0

        // 不为1的一行换到第r行
        for(int j=c;j<=n;j++) swap(a[r][j],a[t][j]);
        // 异或消 第r行消去他们的第c列
        for(int i=0;i<n;i++)
            if(i!=r&&a[i][c])
                for(int j=n;j>=c;j--)
                    a[i][j]^=a[r][j];
        r++;
    }
    if(r<n)
    {
        for(int i=r;i<n;i++)
            if(a[i][n]) return -1;
        return r;
    }
    return r;
}

bitset优化异或方程组

bitset的原理大概是将很多数压成一个,从而节省空间和时间,时间复杂度的 w w w通常是32

n n n m m m列,即 n n n个方程 m m m个未知数
int gauss返回矩阵的秩
注意bitset对于字符串第位在前,而数字第位表示二进制中数字的最低二进制位

时间复杂度: O ( n 3 w ) O(\frac{n^3}{w}) O(wn3)

#include<bitset>
using namespace std;
const int N=1010;
bitset<N> A[N];
int n,m;
int gauss()
{
    int r,c;
    for(c=0,r=0;c<m;c++)
    {
        int t=r;
        for(int i=r;i<n;i++)
            if(A[i][c]) t=i;
        if(!A[t][c]) continue;
        swap(A[r],A[t]);
        for(int i=0;i<n;i++)
            if(i!=r&&A[i][c])
                A[i]^=A[r];
        r++;
    }
    if(r<m)
    {
        for(int i=r;i<n;i++)
            if(A[i][m]) return -1;
        return r;
    }
    return r;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值