Nim博弈的变形。此题中特殊规定:对于某一堆石子,同样的操作不能进行两次,比如说,在石子第i堆有一次取了四颗石子,那么之后不能再从这堆里取4颗了。
对于有t个石子的某堆,其sg值可以用 将该堆石子变为sg值为0状态 所需操作的最大次数来表示 //不成熟个人想法。。。。
不管是对于这题还是基本的nim博弈,对于某一堆石子来说,其由最初状态到最终态的所有可能过程都可以通过一个树来表示,其某一结点距离叶子的最大距离(只能从上向下移动)即为该结点处的sg值 //之前对于做过的题都进行过这样的思考,好像没遇到什么例外的情况。。。
//***和队友讨论后觉得,这种做法需要一个前提——树上不同层的sg的变化具有较好的连续性,这题具备这个条件。当不具备时还是只能通过借助mex函数解题?***
在这道题里,sg[i]的值 即 i最多可分解为不同加数的个数,显然
sg[0]=0,sg[1~2]=1,sg[3~5]=2,sg[6~9]=3,……,sg[n*(n+1)/2~(n+1)*(n+2)/2-1]=n,……,sg[55~65]=10
得到sg值后,只需通过sg值的异或和来进行判断即可
#include<bits/stdc++.h> using namespace std; int sg[]={0,1,1,2,2,2,3,3,3,3,4,4,4,4,4,5,5,5,5,5,5,6,6,6,6,6,6,6,7,7,7,7,7,7,7,7,8,8,8,8,8,8,8,8,8,9,9,9,9,9,9,9,9,9,9,10,10,10,10,10,10}; int n,t; int main() { while(cin>>n) { int ans=0; while(n--) { cin>>t; ans^=sg[t]; } if(ans) puts("NO"); else puts("YES"); } }