LightOJ 组合游戏 SG函数 SG定理 1199 1296 1315 1229 1401

本文介绍了通过SG函数与SG定理解决六道经典博弈论问题的方法,包括石子游戏、棋盘游戏、项链游戏等,详细分析了每道题目的解题思路与算法实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

SG函数与SG定理练手的题目。

1. LightOJ 1199 - Partitioning Game
题意:有n堆石子(1<=n<=100),每一堆分别有xi个石子(1<=xi<=10000),
一次操作可以使一堆石子变成两堆数目不相等的石子,
最后不能操作的算输,问先手胜还是后手胜。
思路:n堆石子相互独立,所以可以应用SG定理,只需要算出一堆石子的SG函数。
一堆石子(假设有x个)的后继状态可以枚举出来,分别是{1,x-1},{2,x-2},...,{(x-1)/2,x-(x-1)/2},
一堆石子分成的两堆石子又相互独立,再次应用SG定理。所以SG(x) = mex{ SG(1)^SG(x-1), SG(2)^SG(x-2),..., SG((x-1)/2)^SG(x-(x-1)/2) },
最后的答案是SG(x1)^SG(x2)^...^SG(xn)


2. LightOJ 1296 - Again Stone Game
题意:有n堆石子(1<=n<=1000),每一堆分别有xi个石子(1<=xi<=10^9),
一次操作可以拿掉任意一堆石子至少一个但不超过一半的石子,
最后不能操作的算输,问先手胜还是后手胜。
思路:n堆石子相互独立,所以可以应用SG定理,只需要算出一堆石子的SG函数。
一堆石子(假设有x个)的后继状态可以枚举出来,分别是{x-1},{x-2},...,{x-x/2},
把前面若干项打表出来:0 1 0 2 1 3 0 4 2 5 1 6 3 7 0 8 4 9 2 10 5 11 1 12 6 13 3 14 7 15...
可以发现一些规律,SG(x) = x/2 (x为偶数),SG(x) = SG(x/2) (x为奇数)。
最后的答案是SG(x1)^SG(x2)^...^SG(xn)


3. LightOJ 1315 - Game of Hyper Knights
题意:有n个骑士(1<=n<=1000)在无限的棋盘中,给定n个骑士的坐标(xi,yi),(0<=xi,yi<500)。
骑士每一步有六种走法,最后不能移动骑士的算输,问先手胜还是后手胜。
思路:n个骑士相互独立,所以可以应用SG定理。
其一,注意到骑士总是往左边走,并且,是在当前对角线的左边,所以在计算每一格的SG函数时可以按照row+col为定值依次计算。
其二,注意到骑士只有六种走法,所以对于每一格的SG函数值SG(x,y)不会超过6。


4. LightOJ 1229 - Treblecross
题意:给一行只包含'X'和'.'的字符串(3<=字符串长度<=200),两人轮流把某一个'.'变为'X',
首先获得连续三个'X'的获胜(初始状态没有连续三个'X')。
如果先手必胜,则输出所有第一步可以画的位置,否则输出0。
思路:首先,考虑如果初始状态有'X.X'或者'XX'出现,则可以肯定,先手必胜,并且胜的策略就是直接构成三连。
否则, 先手肯定不会在'X'的周围两格的范围内画'X'('..X..'变成死区),根据这个性质,可以把初始状态划分为若干个只有'.'的区域。并且这些区域相互独立。
我们用SG(x)表示长度为x的'.'区域的SG函数值。
可以枚举出所有x状态的后继状态,即在x个'.'中选择一个画成'X',把这段分成了最多两段,可以利用SG定理求出这个后继状态的SG函数值。
所以SG(x) = mex{SG(x-3),SG(x-4),SG(x-5),SG(1)^SG(x-6),SG(2)^SG(x-7)...}。
注意边界SG(0)=0,SG(1)=SG(2)=SG(3)=1。
利用SG定理,可以求出初始状态下的SG函数值ans,即可以得到先手必胜或者必败。
如果必胜,枚举初始状态的所有段的所有位置,假设这段长为n,这个位置把这段分成了x和y两段,
如果ans^SG(n)^SG(x)^SG(y)=0,那么画这个位置就是一种必胜策略。


5. LightOJ 1401 - No Tic-tac-toe
题意:给一行只包含'X','O','.'的字符串(1<=字符串长度<=100),两人轮流把一个'.'变为'X'或'O',
两人规定,字符串中不能出现连续的'X'或者'O',问先手胜还是后手胜
思路:我们可以把这行字符串根据'X'和'O'分割成很多只有'.'的小段,这些小段之间是独立的,
对于一个小段,记它的长度为i,这一段的左边是字符st,右边是字符ed(考虑到这段字符串可能在头部或者尾部,st和ed都有可能是空),那么我们要计算SG(i,st,ed),
我们只需要在st~ed之间枚举'X'和'O',把当前的一段分割成两段,而两段再运用SG定理,就可以计算出SG函数值。
边界是SG(0,random,random)=0。
最后再对所有的小段运用SG定理,即可得到答案。


6. LightOJ 1344 - Aladdin and the Game of Bracelets
题意:给n串项链(1<=n<=50),每串项链分别有ki个珠子(1<=ki<=50),这些珠子的重量分别是w1,w2,...,wki。
现在有一个游戏,定义一种操作为取任意项链上的任意一个珠子,然后把该项链上所有不轻于取的珠子的珠子取下,这样项链可能被分成若干个小段或者消失。两个人轮流进行操作,问谁最终会赢。如果总是先手赢,那么输出所有先手取第一个珠子的方案。
思路:由于n条项链互相独立,根据SG定理所以只需要分别计算各项链的SG函数值。
对于每一条项链,枚举取的珠子,然后把项链分割成若干段,这若干段又构成相互独立的游戏,运用SG定理可以继续分割成更小的部分。边界条件是当只有一个珠子的时候SG函数值为1。
需要注意的是,我们不需要求出每一段(50*50)的SG函数值,因为其中有很多段是不可能达成的,所以用记忆化搜索能剪掉很多不必要的步骤。
最后要求输出先手必胜的所有方案,我们只需要枚举每一种方案,如果这种方案的结果得到SG函数值为0,那么该方案可行。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值