题目地址:
https://www.acwing.com/problem/content/description/4008/
Alice和Bob正在玩一个取石子游戏。共有 n n n个石子,双方轮流采取行动。每当轮到一人行动时,该名玩家需要从石子堆中取走恰好 1 1 1或 2 2 2或 k k k个石子。如果轮到一人行动时,已经没有石子可取,则该名玩家失败。已知,双方都会采取最优策略,且Alice率先行动。请问,最终谁将获胜。
输入格式:
第一行包含整数
T
T
T,表示共有
T
T
T组测试数据。
每组数据占一行,包含两个整数
n
,
k
n,k
n,k。
输出格式:
每组数据输出一行结果,如果Alice获胜,则输出Alice
,否则输出Bob
。
数据范围:
前三个测试点满足,
1
≤
T
≤
10
1≤T≤10
1≤T≤10。
所有测试点满足,
1
≤
T
≤
100
1≤T≤100
1≤T≤100,
0
≤
n
≤
1
0
9
0≤n≤10^9
0≤n≤109,
3
≤
k
≤
1
0
9
3≤k≤10^9
3≤k≤109。
1、
k
k
k不是
3
3
3的倍数,则博弈退化为Bash博弈,
n
=
3
m
,
m
=
0
,
1
,
2
,
.
.
.
n=3m, m=0,1,2,...
n=3m,m=0,1,2,...是必败态;
2、考虑
3
∣
k
3|k
3∣k的情况,如果
n
<
k
n<k
n<k则退化为Bash博弈,如果
n
=
k
n=k
n=k显然是必胜态。我们可以证明,当
n
m
o
d
(
k
+
1
)
n\mod (k+1)
nmod(k+1)是
3
3
3的倍数且不等于
k
k
k的时候,是必败态。这些状态是
{
(
k
+
1
)
m
+
3
c
}
−
{
(
k
+
1
)
m
+
k
}
\{(k+1)m+3c\}-\{(k+1)m+k\}
{(k+1)m+3c}−{(k+1)m+k},这些态之间都是不能一步可达的,并且别的状态一步都到这些状态,从而这些状态是必败态。
代码如下:
#include <iostream>
using namespace std;
int main() {
int T;
scanf("%d", &T);
while (T--) {
int n, k;
scanf("%d%d", &n, &k);
if (k % 3) n % 3 ? puts("Alice") : puts("Bob");
else {
n %= k + 1;
n == k || n % 3 ? puts("Alice") : puts("Bob");
}
}
}
每组数据时空复杂度 O ( 1 ) O(1) O(1)。