类似于石子合并的游戏,在黑板上写下N个数,每次只能将其中的一个数减1(结果为0自动消去),或者将某两个数消去,将其和写在黑板上。
Alice先手,彼此都采用最优策略,将最后一个数消去者获胜。
思路:设s为石子总数,n为总堆数,分3种情况:
(1).全1 :如果n能被3整除,先手败,否则先手胜。
(2).有一个2,其余为1:如果n除以3余数为1,先手败,否则先手胜。
(3)其他情况:
a)1的个数为奇数,先手胜。
b)1的个数为偶数,且s+n-1为奇数,先手胜。
c)1的个数为偶数,且s+n-1为偶数,先手败。
#include <iostream> #include <cstring> #include <cstdio> #include <algorithm> using namespace std; const int MAXN = 50+5; int a[MAXN]; int main() { int t,n,num1,num2; long long sum; scanf("%d",&t); for(int cnt = 1; cnt <= t; cnt++) { scanf("%d",&n); sum = 0; num1 = 0; num2 = 0; for(int i = 0; i < n; i++) { scanf("%d",&a[i]); if(a[i] == 1) num1++; else if(a[i] == 2) num2++; sum += a[i]; } if(num1 == n) { if(n%3 == 0) printf("Case #%d: Bob ",cnt); else printf("Case #%d: Alice ",cnt); } else if(num2 == 1 &&num1 + num2 == n) { if(n%3 == 1) printf("Case #%d: Bob ",cnt); else printf("Case #%d: Alice ",cnt); } else { if(num1%2 == 1) printf("Case #%d: Alice ",cnt); else { if((sum + n -1)%2 == 1) printf("Case #%d: Alice ",cnt); else printf("Case #%d: Bob ",cnt); } } } system("pause"); return 0; }