zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    Java对象的生命周期与作用域的讨论(转)
    [置顶] Oracle学习路线与方法
    Java实现 蓝桥杯 算法训练 未名湖边的烦恼
    Java实现 蓝桥杯 算法训练 未名湖边的烦恼
    Java实现 蓝桥杯 算法训练 未名湖边的烦恼
    Java实现 蓝桥杯 算法训练 最大的算式
    Java实现 蓝桥杯 算法训练 最大的算式
    Java实现 蓝桥杯 算法训练 最大的算式
    Java实现 蓝桥杯 算法训练 最大的算式
    Java实现 蓝桥杯 算法训练 最大的算式
  • 原文地址:https://www.cnblogs.com/atmacmer/p/5249233.html
Copyright © 2011-2022 走看看