题面
今盒子里有 n 个小球,A、B 两人轮流从盒中取球,每个人都可以看到另一个人取了多少个,也可以看到盒中还剩下多少个,并且两人都很聪明,不会做出错误的判断。
我们约定:
每个人从盒子中取出的球的数目必须是:1,3,7 或者 8 个。轮到某一方取球时不能弃权!A 先取球,然后双方交替取球,直到取完。被迫拿到最后一个球的一方为负方(输方)
请编程确定出在双方都不判断失误的情况下,对于特定的初始球数,A 是否能赢?
输入描述
先是一个整数 n (n<100),表示接下来有 n 个整数。
然后是 n 个整数,每个占一行(每个整数 < 104),表示初始球数。
输出描述
程序则输出 n 行,表示 A 的输赢情况(输为 0,赢为 1)。
输入样例
4
1
2
10
18
输出样例
0
1
1
0
题解
动态规划,博弈论
由题,拿走最后一个的人为输家,令 f[i]
表示有 i 个球的时候 A 先手并采取最优策略的胜负情况 。
对于一个状态 f[i]
,其获胜的的条件是 f[i - 1]
,f[i - 3]
,f[i - 7]
,f[i - 8]
中有一个状态为输 ,即只要先手的人拿走球后只要出现必败的状态给后手,则先手必赢。
代码
#include<bits/stdc++.h>
using namespace std;
const int N = 1e4 + 5;
int T, n, a[4] = {1, 3, 7, 8};
bool f[N];
int main() {
f[1] = false;
for (int i = 2; i <= 10000; i++) {
for (int j = 0; j < 4; j++) {
if (i > a[j] && !f[i - a[j]]) f[i] = true;
}
}
cin >> T;
while (T--) {
cin >> n;
if (f[n]) puts("1");
else puts("0");
}
return 0;
}
标题: | 2012年第三届蓝桥杯省赛-J.取球游戏 |
---|---|
链接: | https://www.fightingok.cn/detail/158 |
更新: | 2022-09-18 22:43:56 |
版权: | 本文采用 CC BY-NC-SA 3.0 CN 协议进行许可 |