HDU - 5088 Revenge of Nim II

来源:互联网 发布:网络教育报考什么专业 编辑:程序博客网 时间:2024/05/16 05:01

BestCoder #16  1003

BC首页的题解写得很明白,把元素a[ i ]写成在矩阵第i行的01串,矩阵空间的运算是XOR。

如果这个矩阵满足性质   矩阵的秩=矩阵的行数     ,那么他的任意一个子集XORsum都不相等,且非空子集的XORsum不为0,否则    矩阵的秩 < 矩阵的行数。


直接套上刘汝佳白书上的模板。


#include <iostream>#include <cstdio>#include <cstdlib>#include <cstring>#include <algorithm>#include <cmath>using namespace std;typedef int Matrix[1011][100];Matrix A;int m;//m个方程,n个变量int rank(int m, int n){    int i=0, j=0, k, r, u;    while(i<m && j<n)   //当前正在处理第i个方程,第j个变量    {        r=i;        for(k=i; k<m; k++)            if(A[k][j])            {                r=k;                break;            }        if(A[r][j])        {            if(r!=i)                for(k=0; k<=n; k++)                    swap(A[r][k], A[i][k]);            //消元后第i行的第一个非0列是第j列,且第u>i行的第j列均为0            for(u=i+1; u<m; u++)                if(A[u][j])                    for(k=i; k<=n; k++)                        A[u][k]^=A[i][k];            i++;        }        j++;    }    return i;}int main(){    int T;    scanf("%d", &T);    while(T--)    {        memset(A, 0, sizeof(A));        scanf("%d", &m);        int n=0;        for(int i=0; i<m; i++)        {            LL tmp;            scanf("%I64d", &tmp);            int j=0;            while(tmp)            {                A[i][j++]=tmp%2;                tmp/=2;            }            n=max(n, j);        }        if(m>rank(m, n))            puts("Yes");        else puts("No");    }    return 0;}




看到题解的时候,根据矩阵高斯消元的性质,一行元素可能会多次参与运算,但XOR运算的特点,两个相同的数XOR为0,所以这就相当于一行元素只能参与0或1次运算,这也就符合这个题的要求了。

第一次见到这样的题,还是很有价值的。

依旧感叹数学的魅力!!


0 0
原创粉丝点击