洛谷 P2447 [SDOI2010]外星千足虫
裸的高斯消元求异或方程组
但是怎么考虑最少需要几条信息呢?
考虑我们寻找某列为1的行的过程,实际上就是在找最早出现的那条信息
所以只要找到后break就可以了
#include<bits/stdc++.h>
using namespace std;
const int N = 1050;
const int M = 2050;
int n,m;
bitset<N> g[M];
char s[N];
int ans[N];
int main(){
scanf("%d%d",&n,&m);
for(int i = 1; i <= m; ++ i) {
scanf("%s",s);
for(int j = 0; j < n; ++ j)
if(s[j] == '1') g[i][j + 1] = 1;
int x; scanf("%d",&x);
if(x) g[i][n + 1] = 1;
}
int now, col;
int maxx = -1;
for(now = 1, col = 1; now <= m && col <= n; ++ now, ++ col){
/*for(int i = 1; i <= m; ++ i)
{
printf("%d:\n",i);
for(int j = 1; j <= n + 1; ++ j)
printf("%d ",g[i][j] ? 1 : 0);
puts("");
}*/
int ps = -1;
for(int i = now; i <= m; ++ i){
if(g[i][col]) { ps = i; break; }
}
if(ps == -1) { printf("Cannot Determine\n"); return 0; }
maxx = max(maxx, ps);
if(ps != now) swap(g[now],g[ps]);
for(int i = now + 1; i <= m; ++ i){
if(g[i][col]){
g[i] ^= g[now];
}
}
}
printf("%d\n",maxx);
for(int i = n; i >= 1; -- i){
ans[i] = g[i][n + 1];
for(int j = n; j > i; -- j) ans[i] ^= (ans[j] & g[i][j]);
}
for(int i = 1; i <= n; ++ i)
puts(ans[i] ? "?y7M#" : "Earth");
return 0;
}