题解 P2447 【[SDOI2010]外星千足虫】

YoungNeal

2018-07-03 21:41:01

Solution

题解在博客[食用](https://www.cnblogs.com/YoungNeal/p/9260782.html)效果更佳哦~ ## Solution 显然要高斯消元解异或方程组。 这题 $N$ 有点大,可以用 $bitset$ 优化。 最开始想的是二分找这个满足要求的最小的 $K$,无奈复杂度过不去。 考虑高斯消元的过程,假设当前在消第 $i$ 列,第 $j$ 行,那么一定是从第 $j$ 行向下找一个最小的 $p$ ,满足 $a[p][i]=1$。这里的**最小的**就已经满足题目要求了,不必要在二分了。也就是说,每次 $swap$ 时取一个 $\max$ 即可。 其他就跟高斯消元一模一样了。 ## Code ```cpp #include<cstdio> #include<cctype> #include<bitset> #define N 1005 #define M 2005 #define bi std::bitset<N> #define max(A,B) ((A)>(B)?(A):(B)) int n,m; bi a[M]; int getint(){ int x=0;char ch=getchar(); while(!isdigit(ch)) ch=getchar(); while(isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48),ch=getchar(); return x; } void swap(bi &x,bi &y){bi t=x;x=y;y=t;} signed main(){ n=getint(),m=getint(); for(int i=1;i<=m;i++){ int x; for(int j=1;j<=n;j++){ scanf("%1d",&x); a[i][j]=x; } x=getint();a[i][n+1]=x; } int now,ans=0; for(int i=1;i<=n;i++){ now=i; while(now<=m and !a[now][i]) now++; if(now==m+1){ printf("Cannot Determine"); return 0; } ans=max(ans,now); if(now!=i) swap(a[now],a[i]); for(int j=1;j<=m;j++){ if(j==i) continue; if(!a[j][i]) continue; a[j]^=a[i]; } } printf("%d\n",ans); for(int i=1;i<=n;i++){ if(a[i][n+1]) printf("?y7M#\n"); else printf("Earth\n"); } return 0; } ```