题目链接:点击这里
题意:有一堆石子共有N个。A B两个人轮流拿,A先拿。每次只能拿1,3,4颗,拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出N,问最后谁能赢得比赛。
思路:动态规划。
注意:数据有点水, 也可以通过。
AC代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
const int N = 1e8;
bool f[N + 10];
int main()
{
f[1] = f[3] = f[4] = true;
f[2] = false;
for(int i = 5; i <= N; i++)
{
if(f[i - 1] && f[i - 3] && f[i - 4]) f[i] = false;
else f[i] = true;
}
int T;
cin >> T;
while(T--)
{
int n;
cin >> n;
if(f[n]) puts("A");
else puts("B");
}
return 0;
}
上面动态规划的求解过程直观形象,但时间复杂度略高,然而本题又很难直接想出来,所以,先用SG函数打表找找规律。
打表代码:
#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int N = 50;
int sg[N], s[N];
int a[] = {1, 3, 4};
int main()
{
//freopen("out.txt", "w", stdout);
for(int i = 0; i < N; i++)
{
memset(s, 0, sizeof s);
for(int j = 0; j < 3 && i - a[j] >= 0; j++) s[sg[i - a[j]]] = 1;
for(int j = 0; j < N; j++)
{
if(!s[j])
{
sg[i] = j;
break;
}
}
printf("%d %d\n", i, sg[i]);
}
return 0;
}
打表结果:
0 0
1 1
2 0
3 1
4 2
5 3
6 2
7 0
8 1
9 0
10 1
11 2
12 3
13 2
14 0
15 1
16 0
17 1
18 2
19 3
20 2
21 0
22 1
23 0
24 1
25 2
可以发现,7的整数倍和n%7==2的是必败态。
AC代码:
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
int main()
{
int T;
scanf("%d", &T);
while(T--)
{
int n;
scanf("%d", &n);
if(n % 7 == 0 || n % 7 == 2) puts("B");
else puts("A");
}
return 0;
}