51Nod 1067 Bash游戏 V2

题目链接:点击这里

题意:有一堆石子共有N个。A B两个人轮流拿,A先拿。每次只能拿1,3,4颗,拿到最后1颗石子的人获胜。假设A B都非常聪明,拿石子的过程中不会出现失误。给出N,问最后谁能赢得比赛。

思路:动态规划。

注意:数据有点水,10^8 也可以通过。

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;
}
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容