在一个2*N的格子上,Alice和Bob又开始了新游戏之旅。

这些格子中的一些已经被涂过色,Alice和Bob轮流在这些格子里进行涂色操作,使用两种涂色工具,第一种可以涂色任意一个格子,第二种可以涂色任意一个2*2的格子。每一轮游戏里,他们可以选择一种工具来涂色尚未被染色的格子。需要注意,涂色2*2的格子时,4个格子都应当未被涂色。最后一步涂满所有格子的玩家获胜。

一如既往,Alice先手,最优策略,谁是赢家?

在一个2*N的格子上染色 每次可以染1*1的格子 或者2*2的格子 最后涂满所有格子的人胜 m为已染色格子的个数 Alice先手

1*1的点SG值为1 sg【i】表示连续2*i的SG值 sg【3】 就是连续2*3空白格子  最后对整个棋盘分段 分为连续空白的2*i格子 和 某列中涂过色的格子

假如n = 3
在一个已经涂了一个1*1个格子的情况下,有以下子情况: 
情况1 假如是在第1行第1列的那个格子已经被涂了色

整个棋盘可分为:连续0列的格子+第1列剩下的那一个格子+最后连续2列的格子

ans=sg[0]^1^sg[2]

情况2 假如是在第1行第2列的那个格子已经被涂了色

整个棋盘可分为:连续1列的格子+第2列剩下的那一个格子+最后连续1列的格子

ans=sg[1]^1^sg[1]

情况3 假如是在第1行第3列的那个格子已经被涂了色(其实这个同理情况1)

整个棋盘可分为:连续2列的格子+第3列剩下的那一个格子+连续0列的格子

ans=sg[2]^1^sg[0]

 

在一个已经涂一个2*1个格子的情况下  那么有以下几种子情况

情况1 假如是在第1行第1列的那2个格子已经被涂了色

整个棋盘可分为:连续0列的格子+最后连续2列的格子

ans=sg[0]^sg[2]

情况2 假如是在第1行第2列的那2个格子已经被涂了色

整个棋盘可分为:连续1列的格子+最后连续1列的格子

ans=sg[1]^sg[1]

情况3 同理情况1

为什么1*1的SG值为1

它的后继,涂一个格子,然后没有空白格子,后继值也就是sg[0] = 0

取自然数的补集,再从集合里去最小元素,就是1

sg[1]怎么求,他的后继就是涂了一个格子后,剩1个格子。

sg[1]的后继的sg值为1,取补取最小值后,为0,sg[1]=0

sg[2]怎么求,他的后继

后继1:涂了2*2的格子后,后继的sg值为0(sg[0])

后继2:涂1个1*1格子后,剩一个格子和一个2*1,也就是1^s[1]=1

sg[2]的后继的sg值有0,1,取补取最小值后,为2,sg[2]=2

sg[3]怎么求,他的后继

后继1:涂1个1*1格子后,剩一个格子和一个2*2,也就是1^s[2]=3

后继2:涂1个1*1格子后,剩一个格子和2个2*1,也就是1^s[1]^sg[1]=1

后继3:涂1个2*2,剩一个2*1,也就是sg[1]=0

sg[3]的后继的sg值有0,1,3,取补取最小值后,为2,sg[3]=2

sg[4]........

Sample Input
2
2 0 // n m
2 2 //n m
1 1 //已染色格子的坐标
2 2

Sample Output
Case 1: Alice
Case 2: Bob

 # include <iostream>
# include <cstdio>
# include <cstring>
# include <algorithm>
# include <string>
# include <cmath>
# include <queue>
# include <list>
# define LL long long
using namespace std ;
const int MAXN=;
int sg[MAXN];
bool vis[MAXN];
bool g[][MAXN];
int mex(int x)
{
if(sg[x]!=-)return sg[x];
memset(vis,false,sizeof(vis));
for(int i=;i<=x--i;i++) //染1*1
{
int tmp=mex(i)^mex(x--i)^;
vis[tmp]=true;
}
for(int i=;i<=x--i;i++)//染2*2
{
int tmp=mex(i)^mex(x--i);
vis[tmp]=true;
}
for(int i=;;i++)
if(!vis[i])
{
sg[x]=i;
break;
}
return sg[x];
} int main()
{ memset(sg,-,sizeof(sg));
sg[]=;
for(int i=;i<;i++)
sg[i]=mex(i);
int T;
scanf("%d",&T);
int iCase=;
while(T--)
{
int n,m;
scanf("%d%d",&n,&m);
memset(g,false,sizeof(g));
int u,v;
while(m--)
{
scanf("%d%d",&u,&v);
u--;v--;
g[u][v]=true;
}
int len=;
int ans=;
for(int i=;i<n;i++)
{
if(g[][i]||g[][i])
{
ans^=sg[len];
len=;
if(g[][i]&&g[][i])continue;
ans^=;
}
else len++;
}
ans^=sg[len];
iCase++;
if(ans)printf("Case %d: Alice\n",iCase);
else printf("Case %d: Bob\n",iCase);
}
return ;
}

hdu 4559 涂色游戏(SG)的更多相关文章

  1. hdu 4559 涂色游戏(对SG函数的深入理解,推导打SG表)

    提议分析: 1 <= N <= 4747 很明显应该不会有规律的,打表发现真没有 按题意应该分成两种情况考虑,然后求其异或(SG函数性质) (1)找出单独的一个(一列中只有一个) (2)找 ...

  2. hdu 4559 涂色游戏 博弈论

    构造SG函数:sg[i]表示2*i的sg值!! 代码如下: #include<iostream> #include<stdio.h> #include<algorithm ...

  3. NOIp十连测 涂色游戏

    [问题描述]小A 和小B 在做游戏.他们找到了一个n 行m 列呈网格状的画板.小A 拿出了p 支不同颜色的画笔,开始在上面涂色.看到小A 涂好的画板,小B 觉得颜色太单调了,于是把画板擦干净,希望涂上 ...

  4. [CSP-S模拟测试]:涂色游戏(DP+组合数+矩阵快速幂)

    题目描述 小$A$和小$B$在做游戏.他们找到了一个$n$行$m$列呈网格状的画板.小$A$拿出了$p$支不同颜色的画笔,开始在上面涂色.看到小$A$涂好的画板,小$B$觉得颜色太单调了,于是把画板擦 ...

  5. HDU 1536 S-Nim (组合游戏+SG函数)

    题意:针对Nim博弈,给定上一个集合,然后下面有 m 个询问,每个询问有 x 堆石子 ,问你每次只能从某一个堆中取出 y 个石子,并且这个 y 必须属于给定的集合,问你先手胜还是负. 析:一个很简单的 ...

  6. LYDSY模拟赛day3 涂色游戏

    /* 非常好的题 */ #include <cstdio> #include <iostream> #include <cstdlib> #include < ...

  7. 联赛模拟测试5 涂色游戏 矩阵优化DP

    题目描述 分析 定义出\(dp[i][j]\)为第\(i\)列涂\(j\)种颜色的方案数 然后我们要解决几个问题 首先是求出某一列涂恰好\(i\)种颜色的方案数\(d[i]\) 如果没有限制必须涂\( ...

  8. 【矩阵乘优化DP】涂色游戏

    题目大意 用 \(p\) 种颜色填 \(n\times m\) 的画板,要求任意相邻两列的颜色数都不少于 \(q\) ,求方案数. 数据范围 \(1\leq n\leq 100,1\leq m\leq ...

  9. [NOI Online #2 提高组]涂色游戏 题解

    题目描述 你有 1020 个格子,它们从 0 开始编号,初始时所有格子都还未染色,现在你按如下规则对它们染色: 编号是 p1 倍数的格子(包括 0号格子,下同)染成红色. 编号是 p2 倍数的格子染成 ...

随机推荐

  1. python---基础知识回顾(八)数据库基础操作(sqlite和mysql)

    一:sqlite操作 SQLite是一种嵌入式数据库,它的数据库就是一个文件.由于SQLite本身是C写的,而且体积很小,所以,经常被集成到各种应用程序中,甚至在iOS和Android的App中都可以 ...

  2. python---web微信开发

    一:轮询,长轮询,WebSocket了解 轮询: 在前端,设置时间内,一直向后端发送请求.例如:使用setInterval方法设置定时器,一秒向后端发送一次请求,去主动获取数据,进行更新由于前端一直请 ...

  3. 戴尔R720xd服务器系统安装前期环境实现

    型号:R720xd 开启服务器,Ctrl+R进入raid配置 配置完raid后F2对硬盘进行格式化 保存并重启 F11进入BIOS选项设置U盘启动 选择U盘启动 开始进行系统安装!

  4. Java并发编程原理与实战二:并行&并发&多线程的理解

    1.CPU的发展趋势: 核心数目依旧会越来越多,根据摩尔定律,由于单个核心性能提升有着严重的瓶颈问题,普通的PC桌面在2018年可能回到24核心. 2.并发和并行的区别: 所有的并发处理都有排队等候, ...

  5. python核心编程笔记——Chapter2

    对于.py文件,任何一个空的式子都不会有什么输出,如下: #!/usr/bin/env python #-*-coding=utf-8-*- #无任何效果,空语句 1 + 2 * 4 对于i++,++ ...

  6. 用CSS3写圆角(超简单)

    前缀: -moz(例如 -moz-border-radius)用于Firefox-webkit(例如:-webkit-border-radius)用于Safari和Chrome. CSS3圆角(所有的 ...

  7. 2016-2017-20155329 《Java程序设计》第5周学习总结

    学号 2016-2017-20155329 <Java程序设计>第5周学习总结 教材学习内容总结 Java中所有错误都会被打包为对象,运用try.catch,可以在错误发生时显示友好的错误 ...

  8. Python中的and和or

    引子: 出现以上情况的原因是什么呢? print(bool('')) # False print(bool(0)) # False 所有变量的位操作都是通过强制转换成bool实现的,并且表达式的值是从 ...

  9. 使用 TypeScript 改造构建工具及测试用例

    最近的一段时间一直在搞TypeScript,一个巨硬出品.赋予JavaScript语言静态类型和编译的语言. 第一个完全使用TypeScript重构的纯Node.js项目已经上线并稳定运行了. 第二个 ...

  10. [转] A*寻路算法C++简单实现

    参考文章: http://www.policyalmanac.org/games/aStarTutorial.htm   这是英文原文<A*入门>,最经典的讲解,有demo演示 http: ...