Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others)
2 3 2 2 1 2 2 1 3 2 0 1 1 1 1 1 3 3 0 0 0 2 0 0 0 1 0 0
Case 1: 1 0 Case 2: 8 0
#include<iostream> #include<cstdio> #include<cstring> using namespace std; int n,m,A[50][50]; int q,B[50][50]; int Gauss() { int i = 0,j = 0,k,u,r; while(i < n && j < m) //处理第i个方程,第j个变量 { r = i; for(k = i+1; k < n; k++) { if(A[k][j]) { r = k; break; } } if(A[r][j]) { if(r != i) { for(k = 0; k <= m; k++) swap(A[r][k],A[i][k]); } for(k = i+1; k < n; k++) //进行异或消元 if(A[k][j]) { for(u = j; u <= m; u++) A[k][u] ^= A[i][u]; } i++; } j++; } //判断解的情况 for(k = i; k < n; k++) if(A[i][m]) return -1; return i; } int main() { int t,cas = 1; cin>>t; while(t--) { cin>>n>>m; memset(B,0,sizeof(B)); for(int i = 0; i < m; i++) { int k; cin>>k; while(k--) { int var; cin>>var; B[var-1][i] = 1; } } cin>>q; printf("Case %d:\n",cas++); while(q--) { memcpy(A,B,sizeof(B)); for(int i = 0; i < n; i++) cin>>A[i][m]; int ans = Gauss(); if(ans == -1) printf("0\n"); else cout<<(1LL<<(m-ans))<<endl; } } return 0; }
#include <iostream> #include <cstdio> #include <cstring> #include <algorithm> using namespace std; const int maxn=55; struct matrix{ int f[maxn][maxn]; }e,g; int Gauss(matrix a,int m,int n)//高斯消元 { int i=1,j=1,k,r,u; while(i<=m&&j<=n)//处理第i个方程,第j个变量 { r=i; for(k=i;k<=m;k++) if(a.f[k][j]){r=k;break;} if(a.f[r][j]) { if(r!=i)for(k=0;k<=n+1;k++)swap(a.f[r][k],a.f[i][k]); for(u=i+1;u<=m;u++)if(a.f[u][j]) for(k=i;k<=n+1;k++)a.f[u][k]^=a.f[i][k]; i++; } j++; } for(u=i;u<=m;u++)//判断无解 if(a.f[u][n+1])return -1; return i-1; } int main() { int T,tt=0; cin>>T; while(T--) { int i,j,k,n,m,a,b,q,r; cin>>n>>m; memset(e.f,0,sizeof(e.f)); for(i=1;i<=m;i++) { cin>>k; for(j=0;j<k;j++) { cin>>a; e.f[a][i]=1; } } cout<<"Case "<<++tt<<":"<<endl; cin>>q; while(q--) { for(i=1;i<=n;i++) { cin>>a; e.f[i][m+1]=a; } r=Gauss(e,n,m);//求出有界遍历个数r if(r==-1)cout<<0<<endl; else cout<<(1LL<<(m-r))<<endl;//注意范围,超int } } return 0; }