[SDOI2010]外星千足蟲
阿新 • • 發佈:2018-12-22
題目要求解線性方程組,不過這次是要在模2的意義下做。也就是相當於把變數互相異或。
本題用\(O(n^3)\)的高斯消元過不了,不過在互相異或的情況下,消元其實就是兩個方程組直接互相異或,用bitset優化一下即可。
至於如何求最少使用的方程,因為每次都是找一個最小的,使得當前位為1的方程,所以這個就直接符合使用最少的方程,無需特殊處理。
#include<cstdio> #include<algorithm> #include<cstring> #include<iostream> #include<cmath> #include<set> #include<vector> #include<map> #include<queue> #include<bitset> #define rep(i,a,n) for(int i = a;i <= n;i++) #define per(i,n,a) for(int i = n;i >= a;i--) #define enter putchar('\n') #define fr friend inline #define y1 poj #define mp make_pair #define pr pair<int,int> #define fi first #define sc second #define pb push_back using namespace std; typedef long long ll; const int M = 10005; const int INF = 1000000009; const double eps = 1e-7; int read() { int ans = 0,op = 1;char ch = getchar(); while(ch < '0' || ch > '9') {if(ch == '-') op = -1;ch = getchar();} while(ch >= '0' && ch <= '9') ans = ans * 10 + ch - '0',ch = getchar(); return ans * op; } int n,m,ans; char s[2005]; bitset<5> a[2005]; void print() { rep(i,1,m) cout << a[i] << endl; } void gauss() { int r = 0; rep(i,1,n) { int j = r + 1; while(!a[j][i] && j <= m) j++; if(j == m + 1) {ans = -1;return;} else ans = max(ans,j); r++,swap(a[r],a[j]); rep(k,1,m) if(k != r && a[k][i]) a[k] ^= a[r]; } } int main() { n = read(),m = read(); rep(i,1,m) { scanf("%s",s+1); rep(j,1,n) a[i][j] = s[j] - '0'; a[i][n+1] = read(); } gauss(); if(ans == -1) printf("Cannot Determine\n"); else { printf("%d\n",ans); rep(i,1,n) a[i][n+1] ? printf("?y7M#\n") : printf("Earth\n"); } return 0; }