• (转)巴氏(bash)威佐夫(Wythoff)尼姆(Nim)博弈之模板


    感谢:巴氏(bash)威佐夫(Wythoff)尼姆(Nim)博弈之模板

    转自:http://colorfulshark.cn/wordpress/巴氏(bash)威佐夫(wythoff)尼姆(nim)博弈之模板-823.html

    最近研究了一下博弈论(听起来很高大上),当然,这只是博弈论中的冰山一角,但不可否认,巴氏(bash)博弈,威佐夫(Wythoff)博弈和尼姆(Nim)博弈这三种在ACM比赛中也是相当重要的,而最大的问题就是,博弈理解起来有较大的难度,即使理解了,也很难快速转换成代码,这对于做题来说是很不利的,于是,我就决定写一套模板,包括多一点接口,从而方便以后的使用,当然,虽然说是自己写的,但也是参考了别人的代码,所以别告我侵权哈。大笑

    首先是Bash(巴氏)博弈,这是比较简单的一种,原理就不解释了,相信大家都懂,代码很简短,只需要输入这一堆石子的数目,输赢立刻见分晓

    #include<iostream>   
    using namespace std;   
    int main(void)   
    {   
        int cas,total,price;   
        scanf("%d",&cas);   
        while(cas--)   
        {   
            scanf("%d%d",&total,&price);   
            if(total%(price+1))   
                cout<<"先手赢"<<endl;   
            else   
                cout<<"先手输"<<endl;   
        }   
        return 0;   
    }   

    接下来上威佐夫(Wythoff)博弈,石子变成两堆,难度也大幅提升,但是

    #include<iostream>  
    #include<cmath>  
    #include<stdio.h>  
    using namespace std;  
    int main ()  
    {  
        int a,b,dif;  
        double p=(sqrt((double)5)+1)/double(2);  
        while(cin>>a>>b)  
        {  
            dif=abs(a-b);//取差值  
            a=a<b?a:b;//取较小的值  
            if(a==(int)(p*dif))//判断是不是奇异局势  
                printf("0
    ");  
            else printf("1
    ");  
        }  
        return 0;  
    }  

    我擦,为毛代码还是这么短惊恐,大神膜拜中。。。(过奖过奖生气,如有雷同,请相信这真的只是借鉴)

    最后奉上尼姆(Nim)博弈,这种博弈其实就是分解成简单的博弈再一一求解

    #include <stdio.h>  
    #include <string.h>  
    #include <algorithm>  
    #include <iostream>  
    using namespace std;  
    int a[200005],ans[200005][2];  
    int main()  
    {  
        int n,i,j,cnt,s;  
        while(~scanf("%d",&n),n)  
        {  
            cnt = 0;  
            s = 0;  
            for(i = 0; i<n; i++)  
            {  
                scanf("%d",&a[i]);  
                s^=a[i];  
            }  
            for(i = 0; i<n; i++)  
            {  
                if(a[i] > (s^a[i]))  
                {  
                    ans[cnt][0] = a[i];  
                    ans[cnt][1] = s^a[i];  
                    cnt++;  
                }  
            }  
           if(cnt)//判断先手是胜是负  
            {  
                printf("Yes
    ");  
                for(i = 0; i<cnt; i++)  
                    printf("%d %d
    ",ans[i][0],ans[i][1]);//输出若先手为胜的走法  
            }  
            else  
                printf("No
    ");  
                cout<<cnt<<endl;//输出使先手为胜的方案的数目  
        }  
        return 0;  
    }  

    这个稍微长一点,因为里面增加了很多步骤,大大方便了题目的求解。

    从今天开始,你就可以骄(zhuang)傲(bi)的说:“今朝获此三模板,从此博弈是水题!”

  • 相关阅读:
    Yii2.0中文开发向导——Yii2中多表关联查询(join、joinwith)(转)
    yii2权限控制rbac之rule详细讲解(转)
    Yii2提交表单提示无法验证
    php 数组排序以及按照某个字段排序
    Yii 框架里数据库操作详解-[增加、查询、更新、删除的方法 'AR模式']
    Yii2的深入学习--自动加载机制(转)
    YII2 自定义日志路径
    Yii2-Redis使用小记
    windows下安装php5.5的redis扩展
    php json_decode返回null
  • 原文地址:https://www.cnblogs.com/kimsimple/p/6793617.html
Copyright © 2020-2023  润新知