HDU ~ 4388 ~ Stone Game II (博弈论)

题意:T组测试数据,给你一个N,每堆有a[i]个石子,两个人轮流操作谁不能操作谁输,问先手赢还是输。

操作分两步: 第一步为:选择任意一堆石子假定石子个数为a,拿走个数不为0的一些石子使得该堆石子剩余k个并且保证(0 < k < a,k^a < a),^为异或符号。第二步为:加入一堆新的石子,石子个数为k^a,当然你也可以使用技能使得加入的石子个数变为(2k)^a。不过每个人每局游戏只能使用一次技能。

思路:先考虑一堆且不用技能的情况。每次操作相当于把一堆数目为a的石子分为了两堆k,k^a。因为牵扯到异或,我们可以从二进制观察,发现操作其实就是把a数字中的1拆出去一部分。比如:a=1101,可以拆为1000,101两堆。所以我们发现,如果a数字二进制中'1'的个数为X,那么我们对于出自于a这一堆的石子,共可以进行X-1次操作。如果X-1为奇数先手赢,否则先手输。

考虑N堆的情况,总共可操作次数为奇数先手赢,否则先手输。

现在考虑用技能,其实用技能就相当于乘2,二进制多了一个0但是对'1'的个数没有影响,所以技能没什么用。


//#include<bits/stdc++.h>
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
using namespace std;
const int MAXN = 1e3 + 5;
int main()
{
    int T, CASE = 1; scanf("%d", &T);
	while (T--)
	{
		int n; scanf("%d", &n);
		int ans = 0;
		while (n--)
		{
			int t; scanf("%d", &t);
			ans += __builtin_popcount(t) - 1; //二进制下1的个数。G++函数 
		}
		if (ans&1) printf("Case %d: Yes\n", CASE++);
		else printf("Case %d: No\n", CASE++);
	} 
    return 0;
}
/*
3
2
1 2
3
1 2 3
4
1 2 3 3
*/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值