题目
题目概要
一个博弈游戏,只有一个数字。两人轮流操作,每次可以将当前的数字
n
0
n_0
n0 减去它的因数
d
(
d
≠
1
∧
d
≠
n
0
)
d\;(d\ne 1\wedge d\ne n_0)
d(d=1∧d=n0),不能操作者输。
问,最初数字是 n n n 时,先手是否有必胜策略。
数据范围与提示
共
1
0
4
10^4
104 组数据,每组数据
1
≤
n
≤
1
0
9
1\le n\le 10^9
1≤n≤109 。
思路
没有什么好的想法,干脆打了个表。震惊地发现,所有奇数都是先手必败!几乎所有偶数都是先手必胜!
为啥是几乎呢?因为我看到 n = 2 n=2 n=2 和 n = 8 n=8 n=8 是先手必败。于是我就这样交了一发,咋 W A \tt WA WA 了?
回来重新看了看表。啊咧咧!竟然 512 512 512 也是先手必败?再翻翻,怎么 32 32 32 也要出事儿?然后 128 128 128 也是反常情形?
好像 2 × 4 k 2\times 4^k 2×4k 都是先手必败诶!好,把这个结论补上去。 n n n 为奇数或者 n = 2 × 4 k n=2\times 4^k n=2×4k 先手必败,否则先手必胜。交一发,过了。
知道结论之后的证明,非常简单,归纳法即可,但是不容易直接想到。现在我们开始归纳法:
- n n n 是奇数。若 n n n 为质数,直接输掉。否则,它的因子都是奇数,于是后继状态都是偶数。并且它的后继状态不是 2 k 2^k 2k,因为 n 0 − d n_0-d n0−d 仍然是 d d d 的倍数,而 d d d 是一个奇因子。所以后继状态都是先手必胜。得证。
- n ≠ 2 k n\ne 2^k n=2k 但是 n n n 为偶数。显然 n n n 不是质数,并且至少有一个奇因子。那么 n n n 减去这个奇因子,就得到了一个先手必败的后继。得证。
- n = 2 k n=2^k n=2k 。若 k k k 为偶数,即 n = 4 k / 2 n=4^{k/2} n=4k/2,那么其存在后继状态 n 0 = 2 k − 1 n_0=2^{k-1} n0=2k−1 是先手必败。若 k k k 为奇数,那么其后继 n 0 = 2 k − 1 n_0=2^{k-1} n0=2k−1 和其他偶数都是先手必胜。得证。
世上只有打表好! O ( T log n ) \mathcal O(T\log n) O(Tlogn) 没烦恼!
代码
#include <cstdio>
using namespace std;
inline int readint(){
int a = 0; char c = getchar(), f = 1;
for(; c<'0'||c>'9'; c=getchar())
if(c == '-') f = -f;
for(; '0'<=c&&c<='9'; c=getchar())
a = (a<<3)+(a<<1)+(c^48);
return a*f;
}
int logtwo(int x){
for(int i=0; true; ++i)
if((1<<i) >= x)
return i;
return -1;
}
int main(){
for(int T=readint(); T; --T){
int n = readint();
if((n&-n) == n && (logtwo(n)&1))
puts("Bob");
else if(n&1) puts("Bob");
else puts("Alice");
}
return 0;
}