HDU5088 Revenge of Nim II(高斯消元求自由元个数 Nim博弈)

linkkkkk
题意:
Nim游戏,去掉任意堆石子后能否使得先手必输。
思路:
求一个子集,每个式子的状态有取或不取两种,分别设为 1 / 0 1/0 1/0
列一个方程看异或值为 0 0 0,是否有解。
求异或线性方程组的自由元个数或解的个数。
由于全 0 0 0是一组解,所以看是否有多组解,即自由元个数是否大于 0 0 0
代码:

ll n,m=42;
ll a[110][110],g[110];
int Gauss(int n,int m)//返回自由元个数
{
    int r, c;
    for(r = 0, c = 0; c < n; c++)
    {
        int t = -1;
        for(int i = r; i < m; i++)
        {
            if(a[i][c])
            {
                t = i;
                break;
            }
        }
        if(t==-1) continue;

        for(int i = c; i < n; i++)///交换
        {
            swap(a[t][i], a[r][i]);
        }

        for(int i = r + 1; i < m; i++)
        {
            if(a[i][c])
                for(int j = c; j <n; j++)
                {
                    a[i][j] =  a[i][j] ^ a[r][j];
                }
        }

        r++;
    }
	return n-r;
    /*if(r < n)
    {
        for(int i = r; i < n; i++)
        {
            if(a[i][n]) return 2;
        }
        return 1;
    }

    for(int i = n - 1; i >= 0; i--)
    {
        for(int j = i + 1; j < n; j++)
        {
        	if(a[i][j])
            a[i][n] ^= a[j][n];
        }
    }
    return 0;*/
}
void solve()
{
    cin >> n;
    for(int i=0;i<n;i++) cin>>g[i];
    for(int i=0;i<m;i++)
    	for(int j=0;j<n;j++)
    		a[i][j]=(g[j]>>i)&1;
    int ans=Gauss(n,m);
    if(ans>0) puts("Yes");
    else puts("No");

}

int main()
{
    int _;cin>>_;
    while(_--) solve();
    return 0;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

豆沙睡不醒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值