zoukankan      html  css  js  c++  java
  • 博弈基础 三大博弈

    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
  • 相关阅读:
    【 D3.js 选择集与数据详解 — 5 】 处理模板的应用
    阿里云至 Windows Azure 的 Linux 虚拟机迁移
    【 随笔 】 JavaScript 图形库的流行度调查
    2015年,新的启程
    【 D3.js 选择集与数据详解 — 4 】 enter和exit的处理方法以及处理模板
    【 随笔 】 财源滚滚
    HelloXV1.77网络功能简介
    【 D3.js 选择集与数据详解 — 3 】 绑定数据的顺序
    【 D3.js 选择集与数据详解 — 2 】 使用data()绑定数据
    保持与 Microsoft Azure Files 的连接
  • 原文地址:https://www.cnblogs.com/Just--Do--It/p/6409230.html
Copyright © 2011-2022 走看看