[JZOJ4024] 石子游戏
Description
Alice 和 Bob 总喜欢聚在一起玩游戏(T_T),今天他(她)们玩的是一款新型的取石子游戏。游戏一开始有N堆石子,Alice 和 Bob 轮流取出石子。在每次操作中,游戏者必须选择其中的一堆石子,并作出下列的其中一种操作:
(1)移去整堆石子
(2)假设石子堆中有X颗石子,取出Y颗石子,其中1<=Y
游戏结束的条件是:取出最后一颗石子的人胜出。众所周知,Alice和Bob都是绝顶聪明的,假设他们在游戏中都采取最优的策略,问最后谁会胜出游戏呢?
Alice先取。
(1)移去整堆石子
(2)假设石子堆中有X颗石子,取出Y颗石子,其中1<=Y
游戏结束的条件是:取出最后一颗石子的人胜出。众所周知,Alice和Bob都是绝顶聪明的,假设他们在游戏中都采取最优的策略,问最后谁会胜出游戏呢?
Alice先取。
Input
第一行包含一个整数T,表示测试数据的组数。
接下来T组测试数据,在每组数据中,第一行包含一个整数N,表示有多少堆石子。第二行N个正整数,分别表示每堆有多少颗石子。
接下来T组测试数据,在每组数据中,第一行包含一个整数N,表示有多少堆石子。第二行N个正整数,分别表示每堆有多少颗石子。
Input
第一行包含一个整数T,表示测试数据的组数。
接下来T组测试数据,在每组数据中,第一行包含一个整数N,表示有多少堆石子。第二行N个正整数,分别表示每堆有多少颗石子。
接下来T组测试数据,在每组数据中,第一行包含一个整数N,表示有多少堆石子。第二行N个正整数,分别表示每堆有多少颗石子。
Sample Input
3 3 3 5 6 4 2 3 6 9 5 3 2 1 1000000 999999
Sample Output
Alice Bob Alice
Data Constraint
20%的数据,N<=5,每堆石子数量少于10
100%的数据,T<=100,N<=100,每堆石子数量不大于1,000,000
100%的数据,T<=100,N<=100,每堆石子数量不大于1,000,000
Summary
题目还有个条件是取第k堆石头j个,j与第k堆石头数互质。
然后构造SG函数。
若石头数是质数,那么对于小于 i 的所有正整数都可以被取到,那么 SGi则是它在质数表的排名+1。
若石头数是一个合数,那么 i 肯定存在某个因子为前面出现过的质数,那么 SGi 就应为最小质因子的 SG 值了。
最后如果所有的SG值xor后为0,后手必胜,否则先手必胜。
Code
1 #include<cstdio> 2 using namespace std; 3 int n,m,i,j,z[500000],sg[1000000]; 4 bool a[1000000]; 5 int main() 6 { 7 scanf("%d",&n); 8 a[1]=true; 9 int ma=1000000; 10 for (int i=2;i<=1000;i++) 11 for (int j=2;j<=ma/i;j++) 12 a[i*j]=true; 13 int sum=0; 14 sg[1]=1; 15 for (int i=1;i<=ma;i++) 16 if (not a[i]) 17 { 18 sum++; 19 z[sum]=i; 20 sg[i]=sum+1; 21 } 22 else 23 for (int j=1;j<=sum;j++) 24 if (i%z[j]==0) 25 { 26 sg[i]=sg[z[j]]; 27 break; 28 } 29 for (int i=1;i<=n;i++) 30 { 31 scanf("%d",&m); 32 int ans=0; 33 for (int j=1;j<=m;j++) 34 { 35 int x; 36 scanf("%d",&x); 37 ans=ans^sg[x]; 38 } 39 if (ans==0) printf("Bob\n"); 40 else printf("Alice\n"); 41 } 42 }