At the beginning of the game they pick N (1<=N<=100) piles of stones, Mr.Frost and his friend move the stones in turn. At each step of the game, the player chooses a pile, removes at least one stone from the pile, the first player can’t make a move, and loses. So smart is the friends of Mr.Frost that Mr.Frost always loses. Having been a loser for too many times, he wants to play a trick. His plan is to remove some piles, and then he can find a way to make sure that he would be the winner after his friends remove stones first.
Now, he wants to know how many ways to remove piles which are able to achieve his purpose. If it’s impossible to find any way, please print “-1”.
2 2 1 1 3 1 2 3
2 2
//
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define maxn 110
using namespace std;
typedef int Int;
int T, N;
int beg[maxn], end[maxn], x[maxn];
int a[maxn][maxn];
int Gauss_XOR(Int a[maxn][maxn], Int x[maxn], int var, int equ)
{
int row, col;
for (row = col = 1; row <= equ && col <= var; ++row, ++col)
{
if (!a[row][col])
{
for (int i = equ; i > row; --i)
{
if (a[i][col])
{
for (int j = row; j <= var + 1; ++j)
{
swap(a[i][j], a[row][j]);
}
break;
}
}
}
if (!a[row][col])
{
--row;
continue;
}
for (int i = row + 1; i <= equ; ++i)
{
if (a[i][col])
{
for (int j = var + 1; j >= col; --j)
{
a[i][j] ^= a[row][j];
}
}
}
}
for (int i = row; i <= equ; ++i)
{
if (a[i][var + 1]) return -1;
}
if (row <= var)
{
return var - row + 1;
}
for (int i = var; i >= 1; --i)
{
x[i] = a[i][var + 1];
for (int j = i + 1; j <= var; ++j)
{
x[i] ^= a[i][j] && x[j];
}
}
return 0;
}
int main()
{
int num;
scanf("%d", &T);
while (T--)
{
int equ = 0;
memset(x, 0, sizeof (x));
memset(a, 0, sizeof (a));
scanf("%d", &N);
for(int i = 1; i <= N; ++i)
{
int pos = 1;
scanf("%d", &num);
while(num)
{
if(num & 1) a[pos][i] = 1;
else a[pos][i] = 0;
num >>= 1;
++pos;
}
equ = max(equ, pos - 1);
}
for(int i = 1; i <= 32; ++i)
a[i][N + 1] = 0;
int ans = Gauss_XOR(a, x, N, equ);
if (ans == -1) puts("-1");
else
{
int prt = 1;
for(int i = 1; i <= ans; ++i)
{
prt <<= 1;
prt %= 1000007;
}
printf("%d\n", prt);
}
}
return 0;
}
高斯消元法求异或值为0的组合数
该博客介绍了如何使用高斯消元法解决一个数学问题,即在给定的一组整数中找出若干个数字,使得它们的异或值为0。博主通过编写C++代码实现了一个名为Gauss_XOR的函数,该函数接受矩阵和变量数作为参数,并返回解的数量。在主函数中,博主读取输入数据,应用高斯消元并输出结果。如果无法找到异或值为0的组合,则输出-1。

被折叠的 条评论
为什么被折叠?



