• 博弈基础 三大博弈


    Bash游戏

    题目链接

    有1堆石子,共n颗,每次可取1~k颗,先拿完者

    若n%(k+1)==0,则先手必败

    #include<bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        int T;
        cin>>T;
        while(T--)
        {
            int n,k;
            scanf("%d%d",&n,&k);
            if(n%(k+1)==0)
                printf("B
    ");
            else
                printf("A
    ");
        }
    }
    View Code

    Bash游戏_进阶

    题目链接(这是个坑)

    有1堆石子,共n颗,每次可取k(属于集合f)颗,先拿完者

    打表找好规律就好了,下面是打表函数

    #include<bits/stdc++.h>
    using namespace std;
    
    //const int N=;
    int vis[100];
    //int f[N]={};
    
    int main()
    {
        for(int i=1;i<90;i++)
            for(int j=0;f[j]<=i&&j<N;j++)
            {
                if(vis[i-f[j]]==0)
                    vis[i]=1;
            }
        for(int i=0;i<90;i++)
            printf("i=%d:vis[i]=%d
    ",i,vis[i]);
    }
    View Code

    总结:此类博弈不需要考虑sg函数,只需要确定必胜态和必败态,解题思路一般为打败先打表找规律,而后找规律给出统一的公式。打表方式:给定初始条件,然后从低到高枚举某一状态的所有次态,若有存在必败次态,则当前状态为必胜态,否则当前状态必败。

    ===========================================================================================

    Nim游戏

    题目链接

    有n堆石子,每堆有a[i]个石子,先拿完者

    若异或和不为0,则先手必胜

    #include<bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        int n;
        cin>>n;
        int ans=0;
        while(n--)
        {
            int t;
            cin>>t;
            ans^=t;
        }
        if(ans==0)
            printf("B
    ");
        else
            printf("A
    ");
    }
    View Code

    Nim游戏_进阶

    题目链接

    有n堆石子,每堆有a[i]个石子,先拿完者

    若不全是单个石子成堆且异或和不为0,或者全是单个石子成堆且共有偶数堆,则先手必胜

    #include<bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        int T;scanf("%d",&T);
        while(T--)
        {
            int n;scanf("%d",&n);
            int ans=0;
            bool flag=false;
            while(n--)
            {
                int t;
                scanf("%d",&t);
                ans^=t;
                if(t>1) flag=true;
            }
            if(flag&&!ans || !flag&&ans)
                puts("Brother");
            else
                puts("John");
        }
    }
    View Code

    //总结:此类博弈一般需要考虑sg函数,  过段时间再填坑。。。。。。

    ===========================================================================================

    Wythoff游戏

    题目链接

    有两堆石子,每次可以从一堆中取任意个或从2堆中取相同数量的石子,但不可不取,先拿完者

    设少的一堆有a个,多的一堆有b个,k=(1+sqrt(5)/2.0,若a==floor((b-a)*k),则先手必败

    #include<bits/stdc++.h>
    using namespace std;
    
    int main()
    {
        int T,a,b,t;
        double k=(1+sqrt(5))/2.0;
        cin>>T;
        while(T--)
        {
            scanf("%d%d",&a,&b);
            if(a>b) swap(a,b);
            t=b-a;
            printf("%c
    ",a==(int)(t*k)?'B':'A');
        }
    }
    View Code
  • 相关阅读:
    Seq_file文件系统实例剖析
    linux 网卡接收多播MAC(01:08开头)
    linux-3.14.13 看到mpls gso支持
    /usr/include/sys/types.h:62: error: conflicting types for ‘dev_t’
    gcc编译参数-fPIC的一些问题
    glibc-2.15编译error: linker with -z relro support required
    no CONFIG_BQL
    if_nametoindex可以检查网卡名称是否有效
    剑指offer(10)
    剑指Offer(9)
  • 原文地址:https://www.cnblogs.com/Just--Do--It/p/6409230.html
Copyright © 2020-2023  润新知