这个问题就是著名的 巴什博奕(Bash Game)
巴什博奕(Bash Game):只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个。最后取光者得胜。分析
一堆物品共 n 个,两人轮流从中取物,规定每次至少取一个,最多取m 个。最后取光者得胜。
设
n=(m+1)q+r \quad( 0\leq r \leq m ) \\
\quad (\text{i})\quad 若 r=0 ,后取者必胜,策略如下:
若先取者拿走 k 个,则后取者拿走 m+1-k 个,结果剩下 (m+1)(q-1) 个,保持这种取法,则后取者必胜。
\quad (\text{ii})\quad 若 r≠0 ,先取者必胜,策略如下:
先取者先拿走 r 个,若后取者拿走 k 个,则先取者拿走 m+1-k 个,结果剩下 (m+1)(q-1) 个,保持这种取法,则先取者必胜。
总之,要保持给对手留下(m+1) 的倍数,就能最后获胜。
扩展
若规定最后取光者输,设
n-1=(m+1)q+r \quad( 0≤r≤m ) \\
\quad (\text{i})\quad 若 r=0 ,后取者必胜,策略如下: 若先取者拿走 k 个,则后取者拿走 m+1-k 个,结果剩下 (m+1)(q-1)+1 个,保持这种取法,先取者将取到最后一个物品。
\quad (\text{i})\quad 若 r≠0 ,先取者必胜,策略如下: 先取者先拿走 r 个,若后取者拿走 k 个,则先取者拿走 m+1-k 个,结果剩下 (m+1)(q-1)+1 个,保持这种取法,后取者将取到最后一个物品
小游戏
两个人轮流报数,每次至少报一个,最多报十个,谁能报到100 者胜。
附代码:
#include
<cstdio>
#include
<string.h>
#include
<queue>
#include
<algorithm>
#include
<iostream>
using
namespace
std
;
int
main
()
{
int
T
;
scanf
(
"%d"
,
&
T
);
while
(
T
--
){
int
n
,
m
;
scanf
(
"%d%d"
,
&
n
,
&
m
);
if
(
n
%
(
m
+
1
))
printf
(
"first
\n
"
);
else
printf
(
"second
\n
"
);
}
return
0
;
}
参阅:
[1]巴仕博弈(Bash Game)小结
[2]Bash Game hdu 1846
[3]巴什博弈_百度百科