[SDOI2010]外星千足虫

传送门

题目要求解线性方程组,不过这次是要在模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;
}

posted @ 2018-12-22 11:41  CaptainLi  阅读(200)  评论(0编辑  收藏  举报