题目:点击打开链接
题解:每只虫为奇或偶数,所以高消解抑或方程组。
我写的是用unsign int压32位的,注意位运算技巧的应用
发现我高消一直写得很丑,可以直接在消元时得到对角线而不是上三角矩阵,
不用再解方程求答案
#include<bits/stdc++.h>
using namespace std;
#define maxn 2010
unsigned int a[maxn][maxn];
int n,m,ans,t[maxn];
char ch[maxn];
void guass(){
/*for (int i = 0 ; i < m ; i++){
for (int j = 0 ; j <= n ; j++)
cout<<((a[i][j >> 5] >> (j & 31)) & 1);
cout<<endl;
}*/
for (int i = 0 ; i < n ; i++){
int now = -1;
for (int j = i ; j < m ; j++){
if ( a[j][i >> 5] & (1 << (i & 31)) ){ now = j; break; }
}
if ( now == -1 ){ ans = -1; return; }
ans = max(ans,now + 1);
if ( now != i ) for (int j = 0 ; j <= n >> 5 ; j++) swap(a[now][j],a[i][j]);
for (register int j = 0 ; j < m ; j++){ //从0开始消元即可,直接得到对角线
if ( (a[j][i >> 5] & (1 << (i & 31))) && j != i ){
for (register int k = 0 ; k <= n >> 5 ; k++)
a[j][k] ^= a[i][k];
}
}
}
}
void getans(){
for (int i = n - 1 ; i >= 0 ; i--){
t[i] = (a[i][n >> 5] >> (n & 31)) & 1;
// for (int j = i + 1 ; j < n ; j++) t[i] ^= ((a[i][j >> 5] >> (j & 31)) & 1) * t[j]; 不用解方程了!
}
printf("%d\n",ans);
for (int i = 0 ; i < n ; i++){
if ( t[i] ) printf("?y7M#\n");
else printf("Earth\n");
}
}
int main(){
freopen("input.txt","r",stdin);
scanf("%d %d",&n,&m);
for (int i = 0 ; i < m ; i++){
scanf("%s",ch); int t; scanf("%d",&t);
for (int j = 0 ; j < n ; j++){
a[i][j >> 5] += (ch[j] == '1') << (j & 31);
}
a[i][n >> 5] += t << (n & 31);
}
guass();
if ( ans == -1 ) return printf("Cannot Determine\n"),0;
getans();
return 0;
}