高斯消元只要学过线性代数的话理解起来会非常方便,加上kuangbin巨的详细模板还是挺容易的。
#include <iostream>
#include <cstring>
#include <string>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <map>
#include <set>
#include <queue>
#include <vector>
#define mod 1000000007
#define INF 0x3f3f3f3f
#define fuck() (cout << "----------------------------------------" << endl)
using namespace std;
const int maxn = 50 + 5;
int equ,var;
int A[maxn][maxn];
int B[maxn][maxn];
int X[maxn];
bool freex[maxn];
int freenum;
void init()
{
memset(A,0,sizeof(A));
memset(B,0,sizeof(B));
memset(X,0,sizeof(X));
}
void Debug()
{
int i, j;
for (i = 0; i < equ; i++)
{
for (j = 0; j < var + 1; j++)
{
cout << A[i][j] << " ";
}
cout << endl;
}
cout << endl;
}
int gcd(int a, int b)
{
return b == 0 ? a : gcd(b, a % b);
}
int lcm(int a, int b)
{
return a / gcd(a,b) * b;
}
int gauss()
{
int maxrow;
int freexnum;
int freeindex;
int col = 0;
int i,j,k;
for(i=0; i<var; i++)
{
X[i] = 0;
freex[i] = true;
}
for(k=0; k<equ && col<var; k++,col++)
{
maxrow = k;
for(i=k+1; i<equ; i++)
{
if(abs(A[i][col]) > abs(A[maxrow][col])) maxrow = i;
}
if(maxrow != k)
{
for(j=k; j<var+1; j++)
swap(A[k][j],A[maxrow][j]);
}
if(A[k][col] == 0)
{
k--;
continue;
}
for(i=k+1; i<equ; i++)
{
if(A[i][col])
{
int LCM = lcm(abs(A[i][col]),abs(A[k][col]));
int ta = LCM / abs(A[i][col]);
int tb = LCM / abs(A[k][col]);
if(A[i][col] * A[k][col] < 0)
tb *= -1;
for(j=col; j<var+1; j++)
{
A[i][j] = (A[i][j]*ta % 2 - A[k][j]*tb % 2 + 2) % 2;
}
}
}
}
Debug();
cout << k << " QAQ " << " ---- " << col << " QAQ " << endl;
for(i=k; i<equ; i++)//未知数有多少个 对应的秩也就这么多
{
if(A[i][col])
{
//fuck();
return -1;
}
}
if(k < var)
return var - k;
return 0;
}
int main()
{
int T, kases = 1;
scanf("%d",&T);
while(T--)
{
init();
scanf("%d%d",&equ,&var);
for(int i=0; i<var; i++)
{
int t;
scanf("%d",&t);
for(int j=0; j<t; j++)
{
int d;
scanf("%d",&d);
B[d-1][i] = 1;
}
}
printf("Case %d:\n",kases++);
int query;
scanf("%d",&query);
while(query--)
{
memcpy(A,B,sizeof(B));//因为每次修改了A所以在这每次重新赋值
for(int i=0; i<equ; i++)
scanf("%d",&A[i][var]);
//Debug();
int ans = gauss();
if(ans == -1)
printf("0\n");
else
printf("%lld\n", 1LL << (ans));
}
}
return 0;
}
http://www.cnblogs.com/kuangbin/archive/2012/09/01/2667044.html 邝斌高斯消元模板