题目大意
按顺序给出$m$个$n$元模$2$线性方程,问最少当给出多少个方程时整个方程组有解。
题目分析
显然,模$2$可以看做异或。
故本题询问最少几个方程即可使其有解。
利用高斯约旦消元解决该问题,每次选的主元所在行数的最大值即为答案。
代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
| #include<algorithm> #include<iostream> #include<iomanip> #include<cstring> #include<cstdlib> #include<climits> #include<vector> #include<cstdio> #include<cmath> #include<queue>
using namespace std;
inline const int Get_Int() { int num=0,bj=1; char x=getchar(); while(!isdigit(x)) { if(x=='-')bj=-1; x=getchar(); } while(isdigit(x)) { num=num*10+x-'0'; x=getchar(); } return num*bj; }
const int maxn=1005;
int n,m,a[maxn<<1][maxn];
int Gauss_Jordan() { int ans=0; for(int i=1; i<=n; i++) { int row=i; for(; row<=m&&!a[row][i]; row++); if(row>m)return 0; ans=max(ans,row); if(row!=i)for(int j=1; j<=n+1; j++)swap(a[i][j],a[row][j]); for(int j=1; j<=m; j++) if(j!=i&&a[j][i]) for(int k=i; k<=n+1; k++)a[j][k]^=a[i][k]; } return ans; }
int main() { n=Get_Int(); m=Get_Int(); for(int i=1; i<=m; i++) { char s[1005]; scanf("%s",s+1); for(int j=1; j<=n; j++)a[i][j]=s[j]-'0'; a[i][n+1]=Get_Int(); } int ans=Gauss_Jordan(); if(!ans)puts("Cannot Determine"); else { printf("%d\n",ans); for(int i=1; i<=n; i++) { if(a[i][n+1])puts("?y7M#"); else puts("Earth"); } } return 0; }
|