Description
Input
Output
Sample Input
2 3 2 2 3 2 3 3
Sample Output
Alice Bob
如果不是数学大牛,基本上不太可能通过理论分析来求解这道题目,目前我们只知道求解这道题目需要计算每一堆物品的SG值,但这又不是传统的Nim博弈,加上数据范围非常大,那看来我们只有通过规律来求解了,这也是许多博弈问题的解法,幸运的是,一般这种问题的结论都会非常简单。
既然要找规律,那我们就要先手工算出一些SG值,看能否从中看出一些规律,这就考验大家的基础知识了。
就这道题目而言,由于每一堆物品的处理方式是相同的,因此我们可以只考虑一堆物品。
g(0)=0,g(1)=1;这是很显然的
g(2)=2;因为其后继状态为0,1;分解为(1,1)。g(2)=mex(0,1)=2
g(3)=4;其后继为0,1,2,;分解为(1,2)。g(3)=mex(0,1,2,3)=4
g(4)=3;后继为0,1,2,3;分解为(1,3),(2,2),g(4)=mex(0,1,2,4,5)=3
g(5)=5;
g(6)=6;
g(7)=8;
......
也许你已经看出了什么,也许你还是一头雾水,我首先说一下结论
if(n%4==3)
return n+1;
else if(n%4==0)
return n-1;
else
return n;
如果实在看不出来,还可以打一个表,数据量更多的情况下会更容易观察
#include <iostream> #include <cmath> #include <stdio.h> #include <string> #include <cstring> #include <map> #include <set> #include <vector> #include <stack> #include <queue> #include <iomanip> #include <algorithm> using namespace std; int get_sg(int n) { if(n%4==3) return n+1; else if(n%4==0) return n-1; else return n; } int main() { int T,N,heap; int ans; scanf("%d",&T); while(T--) { scanf("%d",&N); ans=0; while(N--) { scanf("%d",&heap); ans^=get_sg(heap); } printf("%s\n",ans==0?"Bob":"Alice"); } return 0; }