ACM
February 20, 2021

博弈论

博弈论

巴什博弈

简介

一堆物品有 n 个,两个人轮流从这堆物品中取物,规定每次可以取走 1 ~ m 个,最后取光者得胜。

解法

显然,如果 n = m + 1,那么由于一次最多只能取 m 个,所以,无论先取者拿走多少个,后取者都能够一次拿走剩余的物品,后者取胜。因此我们发现了如何取胜的法则:如果 n = (m + 1) r + s,(r 为任意自然数,s ≤ m),那么先取者要拿走 s 个物品,如果后取者拿走 k(≤ m) 个,那么先取者再拿走 m + 1 - k 个,结果剩下 (m + 1)(r - 1) 个,以后保持这样的取法,那么先取者肯定获胜。总之,要保持给对手留下 (m + 1) 的倍数,就能最后获胜。

模板

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#define _CRTSECURE_NOWARNINGS
#pragma warning(disable:4996)
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<cctype>
#include<algorithm>
#include<iostream>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<list>
using namespace std;

int C, n, m;

int main()
{
scanf("%d%d", &n, &m);
if (n % (m + 1)) printf("first\n"); //先手胜
else printf("second\n"); //后手胜

return 0;

}

Brave Game

巴什博弈模板题

Good Luck in CET-4 Everybody!

Description

大学英语四级考试就要来临了,你是不是在紧张的复习?也许紧张得连短学期的 ACM 都没工夫练习了,反正我知道的 Kiki 和 Cici 都是如此。当然,作为在考场浸润了十几载的当代大学生,Kiki 和 Cici 更懂得考前的放松,所谓“张弛有道”就是这个意思。这不,Kiki 和 Cici 在每天晚上休息之前都要玩一会儿扑克牌以放松神经。

“升级”?“双扣”?“红五”?还是“斗地主”?

当然都不是!那多俗啊~

作为计算机学院的学生,Kiki 和 Cici 打牌的时候可没忘记专业,她们打牌的规则是这样的:

  1. 总共n张牌;
  2. 双方轮流抓牌;
  3. 每人每次抓牌的个数只能是2的幂次(即:1,2,4,8,16…)
  4. 抓完牌,胜负结果也出来了:最后抓完牌的人为胜者;

假设 Kiki 和 Cici 都是足够聪明(其实不用假设,哪有不聪明的学生~),并且每次都是 Kiki 先抓牌,请问谁能赢呢?

当然,打牌无论谁赢都问题不大,重要的是马上到来的 CET-4 能有好的状态。

Good luck in CET-4 everybody!

Input

输入数据包含多个测试用例,每个测试用例占一行,包含一个整数 n(1<=n<=1000)。

Output

如果 Kiki 能赢的话,请输出 “Kiki”,否则请输出 “Cici”,每个实例的输出占一行。

Sample Input

1
2
1
3

Sample Output

1
2
Kiki
Cici

Solution

如果你是先手,那么请考虑你的必胜点。由于规定只能去 2 的幂次,那么只要你留给对手的牌数为 3 的倍数时,那么你就必赢,因为留下 3 的倍数时,对手有两种情况:

  1. 要么取剩下 1,给你胜利
  2. 要么对手取了一点点儿,轮到你时,你就又可以构造一个 3 的倍数了嘛。

所以无论哪种情况,当你留给对手为 3N 的时候,你是必胜的。好吧,题目说你就是 Kiki,那么当牌数为 3 的倍数时,Kiki 就输了。因为一出来,上帝就留给了 Kiki 一个 3 的倍数。没办法,但是如果一开始上帝留给 Kiki 的不是 3 的倍数,那么 Kiki 肯定能够用先手的优势构造出 3 的倍数,那么 Kiki 就必胜。所以代码是异常的简单啊。

Accepted Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#define _CRTSECURE_NOWARNINGS
#pragma warning(disable:4996)
#include<cstdio>
#include<cstring>
#include<string>
#include<cmath>
#include<cctype>
#include<algorithm>
#include<iostream>
#include<queue>
#include<stack>
#include<vector>
#include<map>
#include<set>
#include<list>
using namespace std;

int n;

int main()
{
while (scanf("%d", &n) != EOF)
{
if (!(n % 3)) printf("Cici\n");
else printf("Kiki\n");
}


return 0;

}

About this Post

This post is written by OwlllOvO, licensed under CC BY-NC 4.0.

#C++#博弈论