• HDU 3404&POJ 3533 Nim积(二维&三维)


    (Nim积相关资料来自论文曹钦翔《从“k倍动态减法游戏”出发探究一类组合游戏问题》)

    关于Nim积计算的两个函数流程:

                           20160307015104


    代码实现如下:

    int m[2][2]={0,0,0,1};
    int Nim_Multi_Power(int x,int y)
    {
        if(x<2)
            return m[x][y];
        int a=0;
        for(;;a++)
            if(x>=(1<<(1<<a))&&x<(1<<(1<<(a+1))))
                break;
        int m=1<<(1<<a);
        int p=x/m,s=y/m,t=y%m;
        int d1=Nim_Multi_Power(p,s);
        int d2=Nim_Multi_Power(p,t);
        return (m*(d1^d2))^Nim_Multi_Power(m/2,d1);
    }
    
    int Nim_Multi(int x,int y)
    {
        if(x<y)
            return Nim_Multi(y,x);
        if(x<2)
            return m[x][y];
        int a=0;
        for(;;a++)
            if(x>=(1<<(1<<a))&&x<(1<<(1<<(a+1))))
                break;
        int  m=1<<(1<<a);
        int p=x/m,q=x%m,s=y/m,t=y%m;
        int c1=Nim_Multi(p,s);
        int c2=Nim_Multi(p,t)^Nim_Multi(q,s);
        int c3=Nim_Multi(q,t);
        return (m*(c1^c2))^c3^Nim_Multi_Power(m/2,c1);
    }


    以下是两道用Nim积来实现的博弈题:

    (1)HDU 3404 Switch lights:http://acm.hdu.edu.cn/showproblem.php?pid=3404

    #include<iostream>
    #include<cstdio>
    using namespace std;
    
    int m[2][2]={0,0,0,1};
    int Nim_Multi_Power(int x,int y)
    {
        if(x<2)
            return m[x][y];
        int a=0;
        for(;;a++)
            if(x>=(1<<(1<<a))&&x<(1<<(1<<(a+1))))
                break;
        int m=1<<(1<<a);
        int p=x/m,s=y/m,t=y%m;
        int d1=Nim_Multi_Power(p,s);
        int d2=Nim_Multi_Power(p,t);
        return (m*(d1^d2))^Nim_Multi_Power(m/2,d1);
    }
    
    int Nim_Multi(int x,int y)
    {
        if(x<y)
            return Nim_Multi(y,x);
        if(x<2)
            return m[x][y];
        int a=0;
        for(;;a++)
            if(x>=(1<<(1<<a))&&x<(1<<(1<<(a+1))))
                break;
        int  m=1<<(1<<a);
        int p=x/m,q=x%m,s=y/m,t=y%m;
        int c1=Nim_Multi(p,s);
        int c2=Nim_Multi(p,t)^Nim_Multi(q,s);
        int c3=Nim_Multi(q,t);
        return (m*(c1^c2))^c3^Nim_Multi_Power(m/2,c1);
    }
    
    int main()
    {
        int t,n,x,y;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d",&n);
            int res=0;
            while(n--)
            {
                scanf("%d%d",&x,&y);
                res^=Nim_Multi(x,y);
            }
            if(res)
                printf("Have a try, lxhgww.
    ");
            else printf("Don't waste your time.
    ");
        }
        return 0;
    }

     

    (2)POJ 3533 Light Switching Game:http://poj.org/problem?id=3533

            上一题是二维Nim积,这道题与之不同的是求三维Nim积,但本质相同。

    #include<iostream>
    #include<cstdio>
    using namespace std;
    
    int m[2][2]={0,0,0,1};
    int Nim_Multi_Power(int x,int y)
    {
        if(x<2)
            return m[x][y];
        int a=0;
        for(;;a++)
            if(x>=(1<<(1<<a))&&x<(1<<(1<<(a+1))))
                break;
        int m=1<<(1<<a);
        int p=x/m,s=y/m,t=y%m;
        int d1=Nim_Multi_Power(p,s);
        int d2=Nim_Multi_Power(p,t);
        return (m*(d1^d2))^Nim_Multi_Power(m/2,d1);
    }
    
    int Nim_Multi(int x,int y)
    {
        if(x<y)
            return Nim_Multi(y,x);
        if(x<2)
            return m[x][y];
        int a=0;
        for(;;a++)
            if(x>=(1<<(1<<a))&&x<(1<<(1<<(a+1))))
                break;
        int  m=1<<(1<<a);
        int p=x/m,q=x%m,s=y/m,t=y%m;
        int c1=Nim_Multi(p,s);
        int c2=Nim_Multi(p,t)^Nim_Multi(q,s);
        int c3=Nim_Multi(q,t);
        return (m*(c1^c2))^c3^Nim_Multi_Power(m/2,c1);
    }
    
    int Nim_Multi2(int x,int y,int z)
    {
        int t=Nim_Multi(x,y);
        return Nim_Multi(t,z);
    }
    
    int main()
    {
        int n,x,y,z;
        while(~scanf("%d",&n))
        {
            int res=0;
            while(n--)
            {
                scanf("%d%d%d",&x,&y,&z);
                res^=Nim_Multi2(x,y,z);
            }
            if(res)
                printf("No
    ");
            else printf("Yes
    ");
        }
        return 0;
    }
  • 相关阅读:
    前端开发和网页设计的过去和未来
    Web开发人员vs网页设计师
    Linux最终将会领先于Windows、Mac OS!
    Linux 大爆炸:一个内核,无数发行版
    因PHP漏洞,超过4.5万个中国网站被攻击
    在 Linux 中自动配置 IPv6 地址
    echart-折线图,数据太多想变成鼠标拖动和滚动的效果?以及数据的默认圈圈如何自定义圆圈的样式
    用TweenMax.js动画让数字动起来
    zrender笔记----(数字Number组件)出现的问题和解决办法
    面试题常考&必考之--js中的数组去重和字符串去重
  • 原文地址:https://www.cnblogs.com/atmacmer/p/5249233.html
Copyright © 2020-2023  润新知