吴昊品游戏核心算法(新年特别篇)—— 1堆级别的取石子游戏(巴什博弈)
吴昊继续,继续摆石子,继续说博弈。之前有说过两种博弈了,这次给出巴什博弈。
巴什博弈是什么?
只有一堆n个物品,两个人轮流从这堆物品中取物,规定每次至少取一个,最多取m个.最后取光者得胜.
用游戏语言表述如下:
1、 本游戏是一个二人游戏;
2、 有一堆石子一共有n个;
3、 两人轮流进行;
4、 每走一步可以取走1…m个石子;
5、 最先取光石子的一方为胜;
巴什博弈的奥义
显 然,如果n=m+1,那么由于一次最多只能取m个,所以,无论先取者拿走多少个,后取者都能够一次拿走剩余的物品,后者取胜.因此我们发现了如何取胜的法 则:如果n=(m+1)r+s,(r为任意自然数,s≤m),那么先取者要拿走s个物品,如果后取者拿走k(≤m)个,那么先取者再拿走m+1-k个,结 果剩下(m+1)(r-1)个,以后保持这样的取法,那么先取者肯定获胜.总之,要保持给对手留下(m+1)的倍数,就能最后获胜.
SG函数
SG(x)=x%(m+1).判断初始状态SG值是否为0,是则为P-position,先手必败。
Solve:
输入为两个数,第一个数为石子的总数,第二个数为每次可以拿走的石子的最多数目,如果先走的人可以赢,则输出first,否则输出second。
1 #include<stdio.h>
2 int main()
3 {
4
5 int t;
6 int n,m;
7 scanf("%d",&t);
8 while(t--){
9 scanf("%d%d",&n,&m);
10
11 //判断是否处在必败点的位置上
12 if(n%(m+1)==0)
13 printf("second\n");
14 else
15 printf("first\n");
16 }
17 return 0;
18 }
2 int main()
3 {
4
5 int t;
6 int n,m;
7 scanf("%d",&t);
8 while(t--){
9 scanf("%d%d",&n,&m);
10
11 //判断是否处在必败点的位置上
12 if(n%(m+1)==0)
13 printf("second\n");
14 else
15 printf("first\n");
16 }
17 return 0;
18 }