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

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


代码实现如下:

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.\n");
else printf("Don't waste your time.\n");
}
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\n");
else printf("Yes\n");
}
return 0;
}

HDU 3404&POJ 3533 Nim积(二维&三维)的更多相关文章

  1. 使用C语言实现二维,三维绘图算法(1)-透视投影

    使用C语言实现二维,三维绘图算法(1)-透视投影 ---- 引言---- 每次使用OpenGL或DirectX写三维程序的时候, 都有一种隔靴搔痒的感觉, 对于内部的三维算法的实现不甚了解. 其实想想 ...

  2. 使用C语言实现二维,三维绘图算法(3)-简单的二维分形

    使用C语言实现二维,三维绘图算法(3)-简单的二维分形 ---- 引言---- 每次使用OpenGL或DirectX写三维程序的时候, 都有一种隔靴搔痒的感觉, 对于内部的三维算法的实现不甚了解. 其 ...

  3. 使用C语言实现二维,三维绘图算法(2)-解析曲面的显示

    使用C语言实现二维,三维绘图算法(2)-解析曲面的显示 ---- 引言---- 每次使用OpenGL或DirectX写三维程序的时候, 都有一种隔靴搔痒的感觉, 对于内部的三维算法的实现不甚了解. 其 ...

  4. ARCGIS二维三维导航

    在使用代码前需要先安装arcgis10.0    或者10.1都可以    不过本人建议初学者安装10.0比较容易安装.. 安装方式和二维三维地图的加载网上都有,就不在此一一赘述了. 先从基本的功能开 ...

  5. HDU 5465 Clarke and puzzle Nim游戏+二维树状数组

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5465 Clarke and puzzle  Accepts: 42  Submissions: 26 ...

  6. POJ 3533 Light Switching Game(三维Nim积)题解

    思路:三维Nim积 代码: #include<set> #include<map> #include<stack> #include<cmath> #i ...

  7. poj 2155:Matrix(二维线段树,矩阵取反,好题)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 17880   Accepted: 6709 Descripti ...

  8. POJ 2155 Matrix (二维线段树)

    Matrix Time Limit: 3000MS   Memory Limit: 65536K Total Submissions: 17226   Accepted: 6461 Descripti ...

  9. poj 1195 Mobile phones(二维树状数组)

    树状数组支持两种操作: Add(x, d)操作:   让a[x]增加d. Query(L,R): 计算 a[L]+a[L+1]……a[R]. 当要频繁的对数组元素进行修改,同时又要频繁的查询数组内任一 ...

随机推荐

  1. Linux 复习重点目录

    Linux安全复习 一.Linux基本命令 1.文件管理命令 lvm 2.用户管理命令 3.网络管理命令 4.权限管理 普通权限和特殊权限 权限命令修改 5.服务命令 6.软件安装管理命令 yum安装 ...

  2. java--调整JVM内存的大小

    默认占用:64M的内存 修改内存的方式: 1.某一类,右键选择--Run Configurations 2.选择--Arguments 3.在VM argments中输入内容,如:-Xmx80m

  3. html使用css让文字多行超出部分用省略号三个点显示的方法案例

    text-overflow: -o-ellipsis-lastline;overflow: hidden;text-overflow: ellipsis;display: -webkit-box;-w ...

  4. zabbix 布署实践【3 proxy安装】

    使用openstack在生产环境创建的一台虚拟机   环境 CentOS7 4核4G内存40G硬盘 IP:10.120.150.150 镜像默认关闭防火墙,selinux ,NetworkManage ...

  5. R安装

    linux: 在编译R之前,需要通过yum安装以下几个程序: #yum install gcc-gfortran              #否则报”configure: error: No F77 ...

  6. uitextfield银行卡加空格

    - (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementS ...

  7. HDU 5033 Building(单调栈)

    HDU 5033 Building(单调栈) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5033 Description Once upon a ti ...

  8. Remote小Demo

    Demo基于http://www.cnblogs.com/zhili/p/NETRemoting.html RemotingObj using System; using System.Collect ...

  9. sql server 查询表基本信息sql

    SELECT c.name,t.name TYPE,c.max_length,c.precision,c.scale,p.value FROM sys.systypes t INNER JOIN sy ...

  10. 12c windows auto installl

    --config for oralce_envset ORACLE_HOME=c:\app\oracle\product\12.1.0\dbhome_1set ORACLE_SID=testuatse ...