【洛谷P2447】外星千足虫

题目大意:给定一个 M 个含 N 个未知数的异或方程组,保证有解,若存在唯一解,给出至少需要几个方程才能得出唯一解,若不存在,直接输出不存在。

题解:异或方程组也满足类似初等行变换的操作,只不过所有的操作都是异或。依旧采用高斯消元来处理异或方程组,即:对于每列来说,从等于当前列的行号开始遍历每一行,找到一个当前列的系数是 1 的行,并进行交换操作。交换后,对改行下面的所有行来说,若当前列的值是 1,则进行异或操作。最后回代即可求出所有的未知数的奇偶性。

代码如下

#include <bits/stdc++.h>
using namespace std;
const int maxn=2010;

bitset<1010> g[maxn];
int n,m,ans,s[maxn];

bool gauss(){
	for(int i=1;i<=n;i++){
		int now=i;
		for(int j=i;j<=m;j++)if(g[j][i]){now=j;break;}
		ans=max(ans,now);
		if(now!=i)swap(g[i],g[now]);
		if(!g[i][i])return 0;
		for(int j=i+1;j<=m;j++)if(g[j][i]==1)g[j]^=g[i];
	}
	for(int i=n;i;i--){
		s[i]=g[i][n+1];
		for(int j=n;j>i;j--)if(g[i][j])s[i]^=s[j];
	}
	return 1;
}

void read_and_parse(){
	scanf("%d%d",&n,&m);
	for(int i=1;i<=m;i++){
		int val;
		for(int j=1;j<=n;j++)scanf("%1d",&val),g[i][j]=val;
		scanf("%d",&val),g[i][n+1]=val;
	}
}
void solve(){
	if(gauss()){
		printf("%d
",ans);
		for(int i=1;i<=n;i++)puts(s[i]?"?y7M#":"Earth");
	}else{
		puts("Cannot Determine");
	}
}
int main(){
	read_and_parse();
	solve();
	return 0;	
}