Description
Alice 和 Bob 总喜欢聚在一起玩游戏(T_T),今天他(她)们玩的是一款新型的取石子游戏。游戏一开始有N堆石子,Alice 和 Bob 轮流取出石子。在每次操作中,游戏者必须选择其中的一堆石子,并作出下列的其中一种操作:
(1)移去整堆石子
(2)假设石子堆中有X颗石子,取出Y颗石子,其中1<=Y 【假的,是取与x 互质(小于等于x)的数】
游戏结束的条件是:取出最后一颗石子的人胜出。众所周知,Alice和Bob都是绝顶聪明的,假设他们在游戏中都采取最优的策略,问最后谁会胜出游戏呢?
Alice先取。
Input
第一行包含一个整数T,表示测试数据的组数。
接下来T组测试数据,在每组数据中,第一行包含一个整数N,表示有多少堆石子。第二行N个正整数,分别表示每堆有多少颗石子。
Output
每组测试数据输出一行,表示获胜者的名字(Alice 或者 Bob)。
通常的 N i m Nim Nim游戏的定义是这样的:有若干堆石子,每堆石子的数量都是有限的,合法的移动是"选择一堆石子并拿走若干颗(不能不拿)",如果轮到某个人时所有的石子堆都已经被拿空了,则判负(因为他此刻没有任何合法的移动)。任何一个 I C G ICG ICG都可以通过把每个局面看成一个顶点,对每个局面和它的子局面连一条有向边来抽象成这个"有向图游戏"。下 面我们就在有向无环图的顶点上定义 S p r a g u e − G r u n d y Sprague-Grundy Sprague−Grundy函数。首先定义 m e x ( m i n i m a l e x c l u d a n t ) mex(minimal excludant) mex(minimalexcludant)运算,这是施加于一个集合的运算,表示最小的不属于这个集合的非负整数。例如 m e x 0 , 1 , 2 , 4 = 3 、 m e x 1 , 3 , 5 = 0 、 m e x = 0 mex{0,1,2,4}=3、mex{1,3,5}=0、mex{}=0 mex0,1,2,4=3、mex1,3,5=0、mex=0。对于一个给定的有向无环图,定义关于图的每个顶点的 S p r a g u e − G r u n d y Sprague-Grundy Sprague−Grundy函数 g g g如下:KaTeX parse error: Expected '}', got 'EOF' at end of input: …)=mex{ g(y) | y是 x x x的后继 }。
s g [ i ] sg[i] sg[i]表示取走 i i i个的 s g sg sg值,因为本题要求必须要是质数,所以取的i是最小质因数。
#include
using namespace std;
int t,n,g,sg[1000001],num;
int main()
{
scanf("%d",&t);
sg[1]=1; num=1;
for (int i=2;i<=1000000;i++)
{
if (!sg[i])
{
sg[i]=++num;
for (int j=i;j<=1000000;j+=i)
if (!sg[j]) sg[j]=num;
}
}
while (t--)
{
int b=0;
scanf("%d",&n);
for (int i=1;i<=n;i++)
scanf("%d",&g),b^=sg[g];
if (b!=0) printf("Alice\n"); else printf("Bob\n");
}
}