HDU 5794 A Simple Nim 2016多校第六场1003

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

题意:给你n堆石子,每一堆有ai石头,每次有两种操作,第一种在任意一堆取出任意数量的石头但不能为0,第二种把一堆石头分成三堆任意数量的石头(不能为0),问是先手赢还是后手赢。

题解:这就是一个Nim游戏!那么Nim游戏一般跟SG函数有关,所以这道题打表找规律即可。

   关于SG函数,在这里也说一下吧!毕竟第一次接触。

   Nim游戏与SG函数:http://baike.baidu.com/link?url=7zmLIrfwIKbxt1JcrcKJ0yzTaCcng_CjGml8OMkhD7N1Jy-AgVGUrfBocLAlzLiGueHj0Dw4EN04ho5VSJb6n_

   首先我们考虑异或(^)运算,显然对于两个不相等的数异或值一定不等于0,反之一定为0。那么我们考虑两堆石头的时候,设定数量分别是a,b。当a=b的时候,也就是异或值为0,对于后手的操作,只要模仿先手即可,为什么?也就是先手取多少,后手就取多少,先手把其中一堆取完,那么后手一定能刚好把另一堆取完,所以后手必胜。那么当a≠b时,此时异或值不等于0,只要先手第一次从多的一堆取出石头使得a=b时,此时后手面对的局面是a=b(异或值为0),从刚才分析可以知道,此时对于a=b,先手跟后手刚好交换了次序,也就是说此时先手必胜。那么我们可以看到,对于两堆石头,数量相等时开始,此时的(从a=b开始)后手可以模仿先手一直到刚好取完。我们可以看到,异或值相等和不相等时分别表示两种局面。我们把对于一个人必败的局面成为P局面(此时异或值为0)。也就是说当先手或者后手面对的局面异或值为0的时候,他必败,另一个人必胜(都用最优策略)。

   那么对于多堆石头,这个结论是否成立呢?答案是肯定的了。那么我们先从异或的运算方法来考虑。异或也就是按位异或,当二进制位中,同一位不同数值时该位异或值为1,相同数值为0。那么当数两个数a,b他们二进制最高位为第k位的时候,两个数的异或值范围为(0~2k+1-1)。由此,当n个数的异或值为c(c的二进制最高位为k)时,那么我们可以知道一定存数的最高位>=k,并且一定存在数>=c。那么从这里可以看出,当n堆石头异或值为0的时候,一次操作后使得异或值改变为c的时候,根据前面可以知道一定有数>-=c,也就是说下一次操作一定可以是的局面再变为0。那么我们可以总结出一个普遍化规律:当当前局面为0的时候,也就是P局面,无论此时的先手怎么操作,此时的后手一定可以是的局面在变为0。因此,n堆石头也符合规律。

   那么,SG函数就是用来描述当前局面。准确来说,SG函数是描述有向无环图游戏局面的。首先定义mex(minimal excludant)运算,这是施加于一个集合的运算,表示最小的不属于这个集合的非负整数。例如mex{0,1,2,4}=3、mex{2,3,5}=0、mex{}=0。那么对于SG(x),sg(x)=mex{ sg(y) | y是x的后继 },y也就是x能够到达的子局面,比如说当前x=3,那么他可以取1个石头到达局面2,取两个到达局面1,取3个到达局面0,也就是说sg(3)=mex{sg(2),sg(1),sg(0)}。那么整个游戏的总和为sg=sg(0)^sg(1)^sg(2)^……^sg(n)。sg(0)=0。

   对于我们来说,SG函数与“游戏的和”的概念不是让我们去组合、制造稀奇古怪的游戏,而是把遇到的看上去有些复杂的游戏试图分成若干个子游 戏,对于每个比原游戏简化很多的子游戏找出它的SG函数,然后全部异或起来就得到了原游戏的SG函数,就可以解决原游戏了。

   回到本题中,题目两种操作,那么对于某一堆的sg值怎么求呢。我们考虑一堆石头数量为x时,那么对于第一种操作,子局面的sg是显然的。对于第二种操作,x分成a,b,c。a+b+c=x,那么这个操作产生的三堆,三个子局面,那么这个子游戏的总和就是sg(a)^sg(b)^sg(c)。比如x=7时,通过第二个操作可以产生子游戏1,2,4。那么这个子游戏的局面就是sg(1)^sg(2)sg(4)=7。

   根据以上,通过递推可知道:

   sg[0]=0

   当x=8k+7时sg[x]=8k+8,

   当x=8k+8时sg[x]=8k+7,

   其余时候sg[x]=x,(k>=0)。

代码如下:

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3
 4 int n;
 5 int cnt;
 6
 7 int main()
 8 {
 9     int t;
10     cin>>t;
11     while(t--)
12     {
13         cnt=0;
14         cin>>n;
15         int a;
16         for(int i=0;i<n;i++)
17         {
18             scanf("%d",&a);
19             if(a%8==0)
20                 cnt^=a-1;
21             else if((a+1)%8==0)
22                 cnt^=a+1;
23             else
24                 cnt^=a;
25         }
26         if(!cnt)
27             puts("Second player wins.");
28         else
29             puts("First player wins.");
30     }
31     return 0;
32 }
时间: 2024-10-06 09:46:45

HDU 5794 A Simple Nim 2016多校第六场1003的相关文章

HDU 5754 Life Winner Bo 2016多校第三场1003

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5754 题意:给你一个n*m大小的棋盘,分别以国际象棋的国王.战车.骑士和皇后的走法从(1,1)走到(n,m),而且只能向右或者向下走,问谁有必胜的策略或者是两者平局. 题解:无论是哪一种移动,都可以注意到,如果从起点到某一个点有必胜的策略,那么再以必胜点作为起点可以走到下一个必胜点,也就是以小见大. 一.对于王的走法,可以注意到3*3大小的棋盘,从(1,1)到(3,3)后手是有必胜的策略的,对于N和

HDU 4923 Room and Moor (多校第六场C题) 单调栈

Problem Description PM Room defines a sequence A = {A1, A2,..., AN}, each of which is either 0 or 1. In order to beat him, programmer Moor has to construct another sequence B = {B1, B2,... , BN} of the same length, which satisfies that: Input The inp

【HDU】4923 Room and Moor(2014多校第六场1003)

Room and Moor Time Limit: 12000/6000 MS (Java/Others)    Memory Limit: 262144/262144 K (Java/Others)Total Submission(s): 263    Accepted Submission(s): 73 Problem Description PM Room defines a sequence A = {A1, A2,..., AN}, each of which is either 0

HDU 5794 - A Simple Nim

题意:    n堆石子,先拿光就赢,操作分为两种:        1.任意一堆中拿走任意颗石子        2.将任意一堆分成三小堆 ( 每堆至少一颗 )        分析:    答案为每一堆的SG函数值异或和.    故先打表寻找单堆SG函数规律.    其中,若 x 可分为 三堆 a,b,c ,则 SG[x] 可转移至子状态 SG[a] ^ SG[b] ^ SG[c]  (三堆SG值异或和)        打表后发现:        SG[ 8*k - 1 ] = 8*k       

多校第六场 1003 hdu 5355 Cake(贪心)

题目链接:(数据加强后wa了) hdu 5355 题目大意: 给出一个蛋糕.切成1~n大小的n块.问是否能在不继续分割的情况下拼凑出m等份. 题目分析: 首先我们是可以知道每份蛋糕的尺寸的,利用n*(n+1)/2m可以算出来,假设不能整除的话,那么一定无解. 然后我们考虑怎样构造一组解,对于一块蛋糕,我想到了一个贪心策咯,尽量选择最大块的蛋糕,由于假设能选可是不选这块蛋糕,那么也一定是通过选取小块的蛋糕来拼凑出这块蛋糕的大小,可是假设小的拼凑出了这块,那么就不能用于拼凑其它的蛋糕,显然选择最大的

2016多校第六场1001-1003(hdu5793&amp;hdu5794&amp;hdu5795)

这场就做出一道题,怎么会有窝这么辣鸡的人呢? 1001 很复杂的公式,打表找的规律,最后是m^0+m^1+...+m^n,题解直接是(m^(n+1)-1)/(m-1),长姿势,原来还能化简……做出来的题不写题解了. 1002 一个棋盘,走棋的姿势要满足(x1-x2)^2+(y1-y2)^2==5,也就是以“日”字走,且只能向右下走. 其中有一些障碍不能经过,注意障碍有可能在终点,求从(1,1)走到(n,m)的路径数. 容斥+组合数 这题的简单版CF559C(对啊,我做过这题,我还是没做出来,wa

?HDU 5795 A Simple Nim(简单Nim)

HDU 5795 A Simple Nim(简单Nim) Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)   Problem Description - 题目描述 Two players take turns picking candies from n heaps,the player who picks the last one will win the game.On e

多校第六场 HDU 4927 JAVA大数类

题目大意:给定一个长度为n的序列a,每次生成一个新的序列,长度为n-1,新序列b中bi=ai+1?ai,直到序列长度为1.输出最后的数. 思路:这题实在是太晕了,比赛的时候搞了四个小时,从T到WA,唉--对算组合还是不太了解啊,现在对组合算比较什么了-- import java.io.*; import java.math.*; import java.util.*; public class Main { public static void main(String[] args) { Sca

2014多校第六场 1005 || HDU 4925 Apple Tree

题目链接 题意 : 给你一块n×m的矩阵,每一个格子可以施肥或者是种苹果,种一颗苹果可以得到一个苹果,但是如果你在一个格子上施了肥,那么所有与该格子相邻(指上下左右)的有苹果树的地方最后得到的苹果是两倍,如果(i,j)有一颗苹果树,(i-1,j)与(i,j+1)施了肥,那么苹果应该是1的两倍2,2的两倍4,最后是4个苹果,问你怎么安排苹果和施肥的格子使最后得到的苹果最多. 思路 : 画了图就可以看出来,苹果和苹果,肥与肥之间不要相邻就好了,所有的苹果之间都有施肥,所有施肥的格子都被苹果隔开了才能