acwing 884. 高斯消元解异或线性方程组

acwing 884. 高斯消元解异或线性方程组

原题链接:https://www.acwing.com/problem/content/886/

思路

异或运算俗称不进位加法

所以可以使用高斯消元来解这个方程组(注意有的地方换成异或运算即可)

高斯消元详解

具体做法:

矩阵化为阶梯型矩阵
	1.枚举每一列
	2.找到非零行
	3.交换到最上面
	4.将下面消成0

如果是完美阶梯型矩阵,则有唯一解
如果最后有 0 0 0 0的情况,无数解
如果最后有 0 0 0 1的情况,无解

代码

#include<iostream>
#include<algorithm>

using namespace std;

const int N = 110;

int n;
int a[N][N];

int gauss()
{
    int r,c;
    
    // 枚举列
    for(r = 0,c = 0; c < n; c ++)
    {
        int t = r;
        for(int i = r; i < n; i ++)
        {
            if(a[i][c]) t = i;
        }
        
        if(!a[t][c]) continue; // 如果不存在非0行就继续枚举列
        
        // 交换
        for(int i = c; i <= n; i ++) swap(a[t][i],a[r][i]);
        
        // 将此列下面变成0->此题是异或方程组,所以不是0异或一下那一行即可
        for(int i = r + 1; i < n; i ++)
        {
            if(a[i][c])
            {
                // 注意要从后往前算
                for(int j = n; j >= c; j --)
                    a[i][j] ^= a[r][j]; // 和第r行对应的进行异或(二进制中异或和加减一样)
            }
        }
        r ++; // 将下一行变成阶梯矩阵中的行
    }
    
    if(r < n)
    {
        for(int i = r; i < n; i ++)
            if(a[i][n]) return 2; // 矛盾无解
        return 1; // 有无穷多解
    }
    
    // 完美阶梯型 解唯一,求出解存在a[0~n-1][n]
    for(int i = n - 1; i >= 0; i --)
    {
        for(int j = i + 1; j < n; j ++)
        {
            a[i][n] ^= a[i][j] * a[j][n];
        }
    }
    
    return 0;
}


int main()
{
    cin >> n;
    for(int i = 0; i < n; i ++)
        for(int j = 0; j < n + 1; j ++) 
            cin >> a[i][j];
            
    int t = gauss();
    
    if(t == 2) puts("No solution");
    else if(t == 1) puts("Multiple sets of solutions");
    else 
    {
        for(int i = 0; i < n; i ++) cout << a[i][n] << endl;
    }
    
    return 0;
}   
posted @ 2022-09-22 17:37  r涤生  阅读(52)  评论(0编辑  收藏  举报