HDU 5794 - A Simple Nim
2024-10-15 05:05:19
题意:
n堆石子,先拿光就赢,操作分为两种:
1.任意一堆中拿走任意颗石子
2.将任意一堆分成三小堆 ( 每堆至少一颗 )
分析:
答案为每一堆的SG函数值异或和.
故先打表寻找单堆SG函数规律.
其中,若 x 可分为 三堆 a,b,c ,则 SG[x] 可转移至子状态 SG[a] ^ SG[b] ^ SG[c] (三堆SG值异或和)
打表后发现:
SG[ 8*k - 1 ] = 8*k
SG[ 8*k ] = 8*k - 1
其余 SG[x] = x;
则可直接得出答案
#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
const int MAXN = ;
int T, n;
int main()
{
scanf("%d", &T);
while ( T-- )
{
scanf("%d", &n);
int sg = ;
for (int i = ; i <= n; i++)
{
int x; scanf("%d", &x);
if (x % == ) sg ^= (x - ) ;
else if ( (x + ) % == ) sg ^= (x + ) ;
else sg ^= x;
}
if(sg) puts("First player wins.");
else puts("Second player wins.");
}
}
/*
SG打表
*/
#include <iostream>
#include <cstring>
using namespace std;
int sg[];
int GetSG(int x)
{
if (sg[x] != -) return sg[x];
int vis[];
memset(vis, , sizeof(vis));
for (int i = ;i < x; i++)
vis[GetSG(i) ] = ;
int a,b,c;
for(a = ; a <= x; a++)
for(b = a; b <= x - a; b++)
for(c = b; c <= x - a - b; c++)
if(a+b+c == x)
vis[GetSG(a) ^ GetSG(b) ^ GetSG(c)] = ;
for(int i = ;; i++)
if(!vis[i]) return sg[x] = i;
}
int main()
{
memset(sg, -, sizeof(sg));
sg[] = ;
for (int i = ; i <= ; i++)
if(sg[i] == -) GetSG(i);
for(int i = ; i <= ; i++)
cout<<i<<" "<<sg[i]<<endl;
}
最新文章
- win8.1 user profile service 服务登录失败
- 使用 Jasmine 进行测试驱动的 JavaScript 开发
- Keepalived安装配置
- Backup: Numbers in Perl6
- 使用MediaPlayer和SurfaceView播放视频
- 访问public
- 结对开发----找出“水王";
- linux网络编程--跳水send和recv
- 如何自定义Intent.createChooser的显示结果
- haml、sass简单的解释
- iis部署wcf服务过程
- 《k8s-1.13版本源码分析》- Informer 机制
- 迄今为止 .Net 平台功能最强大,性能最佳的 JSON 序列化和反序列化库。
- Ubuntu18.04安装mysql5.7
- C语言---斐波那契问题
- centos 64位 下hadoop-2.7.2 下编译
- 第二章:蓝色巨人 IBM公司
- 通过Gson解析Json数据
- 进程调度之FCFS算法(先来先运行算法)
- python的str()字符串类型的方法详解