HDU 3389 Game (阶梯博弈)

题意:

给你n个盒子,从1---n,你每次要找出来两个盒子下表分别是a,b;它们要满足(a+b)%2==1 && (a+b)%3==0,找到盒子之后要从b向a中拿过去至少1个卡牌

最多不限(这里b>a的)

 

阶梯博弈:(尼姆博弈升级)

 这种题目就是只能从高出向低处放东西,谁最后一次放到最低处谁就获胜(比如本题就是从下标大的向下标小的位置放卡牌)

解法:

假设全部东西移到0这个位置就不能走了:

在偶数下标的阶梯是不影响的,因为最后全部东西肯定都移动到了0,而且0不是一个奇数,所以偶数下标移动东西是没有影响的

那么就只有奇数下标会造成影响,那么我们就可以对奇数下标的东西全部异或看他们是不是0就可以了

 

题目的终结点不一定就是0,这里只是举个例子(比如本题是把全部卡牌移动到1、3、4这三个位置之后就结束了)

我们做这样的题只需要找出来那个不影响题目,然后去判断其他影响题目的就可以了

 

参考题解:

1、3、4这3个下标的东西是不能移动的,例如

2-->1    5-->4   6-->3

这些盒子中卡片转移的步数的奇偶性是一定的。为什么这么说呢?
因为即使有些盒子例如编号11的盒子,有11->4和11->10->8->1两种选择,但是这两种选择的步数的奇偶性是相同的,都是奇数,所以奇偶性是一定的。

 

所以我们把这个阶梯博弈转化为尼姆博弈就行了,对步数为奇数的盒子进行尼姆博弈。在纸上多写几个数或者用打表的方法可以发现如下规律:
盒子编号模6为0,2,5的位置的移动步数为奇,其余为偶。

 

代码:

 1 #include <stdio.h>
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <string.h>
 5 #include<math.h>
 6 #include<set>
 7 #include<map>
 8 using namespace std;
 9 const int maxn = 105;
10 const int INF=0x3f3f3f3f;
11 const int mod=1000000007;
12 typedef long long ll;
13 int main()
14 {
15     int t,cas=1;
16     scanf("%d",&t);
17     while(t--)
18     {
19         int n,m,flag=0;
20         scanf("%d",&n);
21         for(int i=1;i<=n;i++)
22         {
23             scanf("%d",&m);
24             if(i%6==2||i%6==5||i%6==0)
25             flag^=m;
26         }
27         if(flag)
28         printf("Case %d: Alice\n",cas++);
29         else
30         printf("Case %d: Bob\n",cas++);
31     }
32     return 0;
33 }
View Code

 

posted @ 2019-08-16 11:00  kongbursi  阅读(173)  评论(0编辑  收藏  举报