算法--高斯消元法

有一种隐忍其实是蕴藏着的一种力量,有一种静默其实是惊天的告白。

这个刚学时,由于大佬给我们讲了一个例题,导致我有些误解,高斯消元法应用到直接求第几大的异或数时有不少不明白的地方,看网上讲解的都是都没有我想要弄明白的地方,于是乎我就向大佬请教,总算是知道了大佬直接求解的方法了。

可是理解思路只是第一步,最关键的还是由代码实现,下面有高斯消元法的详细解释,然后再贴一个模板,用的时候方便些。

点我有惊喜!

代码:

void Gauss() {
    for(int i = 0; i < n; i ++) {
        r = i;
        for(int j = i + 1; j < n; j ++)
            if(fabs(A[j][i]) > fabs(A[r][i])) r = j;
        if(r != i) for(int j = 0; j <= n; j ++) std :: swap(A[r][j], A[i][j]);

        for(int j = n; j >= i; j --) {
            for(int k = i + 1; k < n; k ++)
                A[k][j] -= A[k][i] / A[i][i] * A[i][j];
        }
    }

    for(int i = n - 1; i >= 0; i --) {
        for(int j = i + 1; j < n; j ++)
            A[i][n] -= A[j][n] * A[i][j];
        A[i][n] /= A[i][i];
    }
}

这是一个求解方程组解的总版子:

#include<bits/stdc++.h>
#define re register
#define il inline
#define debug printf("Now is %d\n",__LINE__);
using namespace std;
#define maxn 105
#define D double
D a[maxn][maxn];
int n;
int main()
{
    scanf("%d",&n);
    for(re int i=1;i<=n;++i)
    {
        for(re int j=1;j<=n+1;++j)
        {
            scanf("%lf",&a[i][j]);
        }
    }
    for(re int i=1;i<=n;++i)//枚举列(项)
    {
        re int max=i;
        for(re int j=i+1;j<=n;++j)//选出该列最大系数
        {
            if(fabs(a[j][i])>fabs(a[max][i]))
            //fabs是取浮点数的绝对值的函数
            {
                max=j;
            }
        }
        for(re int j=1;j<=n+1;++j)//交换
        {
            swap(a[i][j],a[max][j]);
        }
        if(!a[i][i])//最大值等于0则说明该列都为0,肯定无解
        {
            puts("No Solution");
            return 0;
        }
        for(re int j=1;j<=n;++j)//每一项都减去一个数(就是小学加减消元)
        {
            if(j!=i)
            {
                re D temp=a[j][i]/a[i][i];
                for(re int k=i+1;k<=n+1;++k)
                {
                    a[j][k]-=a[i][k]*temp;
                    //a[j][k]-=a[j][i]*a[i][k]/a[i][i];
                }
            }
        }
    }
    //上述操作结束后,矩阵会变成这样
    /*
    k1*a=e1
    k2*b=e2
    k3*c=e3
    k4*d=e4
    */
    //所以输出的结果要记得除以该项系数,消去常数
    for(re int i=1;i<=n;++i)
    {
        printf("%.2lf\n",a[i][n+1]/a[i][i]);
    }
    return 0;
}

异或方程组高斯消元模板:

#include<bits/stdc++.h>
using namespace std;
#define MAX_SIZE 350
#define ll long long
ll Matrix[MAX_SIZE][MAX_SIZE];
ll Free_x[MAX_SIZE];   //自由变元
ll X_Ans[MAX_SIZE];  //解集 
ll Free_num=0;  //自由变元数
ll Guass(ll Row,ll Column)  //系数矩阵的行和列
{
    ll row=0,col=0,max_r;
    for(row=0;row<Row&&col<Column;row++,col++)
    {
        max_r=row;
        for(ll i=row+1;i<Row;i++)   //找出当前列最大值
            if(abs(Matrix[i][col])>abs(Matrix[max_r][col]))
                max_r=i;
        if(Matrix[max_r][col]==0)  //记录自由变元
        {
            row--;
            Free_x[Free_num++]=col+1;
            continue;
        }
        if(max_r!=row)  //交换
            for(ll i=col;i<Column+1;i++)
                swap(Matrix[row][i],Matrix[max_r][i]);
        for(ll i=row+1;i<Row;i++)   //消元
        {
            if(Matrix[i][col]!=0)
            {
                for(ll j=col;j<Column+1;j++)
                    Matrix[i][j]^=Matrix[row][j];
            }
        }
    }
    for(ll i=row;i<Row;i++)   //无解
        if(Matrix[i][Column]!=0)
            return -1;
    if(row<Column)   //无穷多解
        return Column-row;
    //唯一解
    for(ll i=Column-1;i>=0;i--)
    {
        X_Ans[i]=Matrix[i][Column];
        for(ll j=i+1;j<Column;j++)
           X_Ans[i]^=(Matrix[i][j]&&X_Ans[j]);
    }
    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值