HDU 3389 Game (阶梯博弈、找规律)*

13 篇文章 0 订阅
6 篇文章 0 订阅

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3389


题意:1-N带编号的盒子,当编号满足A>B && A非空 && (A + B) % 3 == 0 && (A + B) % 2 == 1则可以从A中取任意石头到B中,谁不能取了谁就输。


由已知条件可得到 (A+B) % 6 =  3 ,即((A % 6)+(B % 6))% 6 = 3,于是可以知道  编号%6 == 0的盒子可以转移到  编号%6 == 3的盒子里, 编号%6==1的盒子可以转移到  编号%6==2的盒子...,也就是下面这样:
0 -> 3 -> 0 -> 3
2 -> 1 -> 2 -> 1
5 -> 4 -> 5 -> 4
可以发现(怎么发现的。。。)最后的1, 3, 4盒子都是不能继续转移的盒子。

这三个转移都是互不影响的,所以可分三个子游戏: 
    1.余0的箱子中的卡只能移到余3里,余3的箱子只能移到余0里。最终箱子编号为3; 
    2.余2的箱子中的卡只能移到余1里,余1的箱子只能移到余2里。最终箱子编号为1; 
    3.余4的箱子中的卡只能移到余5里,余5的箱子只能移到余4里。最终箱子编号为4; 
     
对于1子游戏,若一个人从余3移一定数目的卡到余0的a箱里,那另一个也必定可以从a箱中移出相同数目的卡。所以 
我们只用考虑从余0中移出的情况(因为余0中移到3号箱中,另一个就不能从3号箱子移出卡,不能与上述判断等同), 
而从余0中移到余3中可以看做从余0中删除,因为余数3的可以根据上述方式最终移动3中,而先后手顺序不变。 
这就变成了取石子游戏了,sg[i]=i。 其余的2,3同理。最终求得的sg函数值,异或便是结果了。


另一种解释:对于第一个转移公式我们可以发现如果当前决策者处于不利形势,他想要挽回形式而移动x%6==3的盒子到x%6==0的盒子是完全没用的,因为对手总是可以继续把你转移的盒子再转移回x%6==3的盒子里使得你还是处于同样的劣势,所以在这里影响结果的只有x%6==0的盒子,最终是要把x%6==0的盒子里的移动到3这个盒子里,问题似乎就转换成了普通的NIM取石子游戏。。。sg值就是和NIM游戏一样为盒子里的卡片数!对于其他两个转移公式同样如此!


参考博客:http://blog.csdn.net/a601025382s/article/details/11910303

http://www.2cto.com/kf/201311/255113.html


#include <iostream> 
#include <cstring>
#include <cstdio>
#include <algorithm>
using namespace std;
int main() {
	int t;
	scanf("%d", &t);
	int kase = 1;
	while(t--) {
		int n;
		scanf("%d", &n);
		int a[10010];
		int i, ans = 0;
		for(i = 1; i <= n; i++) {
			scanf("%d", a + i);
			if(i % 6 == 0 || i % 6 == 2 || i % 6 == 5) {
				ans ^= a[i];
			}
		}
		if(ans) printf("Case %d: Alice\n", kase++);
		else printf("Case %d: Bob\n", kase++);
	}
	return 0;
}


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值