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;
}
rds_blogs