萌新学习SG函数与SG定理(含uva1378 - A Funny Stone Game题解)

本文探讨了NIM游戏的策略,介绍了如何通过计算异或和确定先手胜负,并引入了SG函数和SG定理的概念,解释了在复杂游戏场景中判断必胜必败状态的方法。

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

先从NIM游戏说起

n n n堆石子,第 i i i堆石子的个数为 a i a_i ai
每个人每次只能从一堆种取若干个石子,最后不能取的人输,两个人都绝顶聪明,问先手必胜还是必败
结论是这样的:
如果 a 1 ⊕ a 2 ⊕ . . . ⊕ a n = 0 a_1\oplus a_2\oplus ...\oplus a_n=0 a1a2...an=0,那么先手必败,否则先手必胜
为了便于叙述,我把 a 1 ⊕ a 2 ⊕ . . . ⊕ a n = 0 a_1\oplus a_2\oplus ...\oplus a_n=0 a1a2...an=0叫做 a 1 . . . a n a_1...a_n a1...an n n n个数字的 n i m nim nim和(异或和)
证明可以用数学归纳法:

基础

如果每堆石子的个数都是 0 0 0,那么先手已经无法操作,此时先手必败

归纳

假设当前总石子数为 S S S总石子数为 k &lt; S k&lt;S k<S时该结论成立

  • n i m nim nim和等于 0 0 0时,假设我取第 i i i堆里的石子,显然 a i &gt; 0 a_i&gt;0 ai>0,因为 a i a_i ai与其它石子堆的 n i m nim nim和为 0 0 0,所以其它石子堆的 n i m nim nim和就等于 a i a_i ai,不管我在 a i a_i ai中取几个石子,取完之后这一堆里面剩下的石子数 a i ′ ̸ = a i a_i&#x27;\not = a_i ai̸=ai,那么总的 n i m nim nim和也就不再等于 0 0 0,根据假设,这时我处于必胜态,也就是说最开始的状态就是先手必败态。
  • n i m nim nim和不等于 0 0 0时,假设 n i m nim nim和为 k k k,考虑 k k k二进制最高位上的 1 1 1,肯定有至少一堆石子的这一位也是 1 1 1,就随便取其中一堆,不妨设它是第 i i i堆,设其余堆的 n i m nim nim和为 x x x,那么 a i ⊕ x = k a_i\oplus x=k aix=k。我把第 i i i堆取成 a i ⊕ k a_i\oplus k aik,那么最后的 n i m nim nim和就是 ( a i ⊕ k ) ⊕ x = 0 (a_i\oplus k) \oplus x = 0 (aik)x=0,而 a i ⊕ k &lt; a i a_i\oplus k &lt; a_i aik<ai,也就是说着这种方案一定存在。根据假设,取完之后我面临先手必败局面,也就是说一开始我处于先手必胜态

结论

根据数学归纳法第二原理,若 n n n堆石子的异或和为 0 0 0则先手必败,否则先手必胜。

SG函数、SG定理

这一部分的具体原理目前还没看懂…具体请详见《由感性认识到理性认识——透析一类搏弈游戏的解答过程》
对于这样的游戏:
双方轮流操作,不能操作的输
双方的操作规则是相同的
无论怎样操作,游戏总能在有限步内完成
就是说对于每种局面 x x x,给一个函数值 S G ( x ) SG(x) SG(x),假设 x x x的后继局面为 x 1 , x 2 , x 3 . . . x k x_1,x_2,x_3...x_k x1,x2,x3...xk,那么 S G ( x ) = m e x { S G ( x 1 ) , S G ( x 2 ) , . . . , S G ( x k ) } SG(x)=mex\{SG(x_1),SG(x_2),...,SG(x_k)\} SG(x)=mex{SG(x1),SG(x2),...,SG(xk)} m e x ( A ) mex(A) mex(A)表示不存在在集合 A A A中的最小自然数( A A A是自然数集的有限子集)。
S G ( x ) = 0 SG(x)=0 SG(x)=0则局面 x x x为必败态,否则为必胜态
游戏的和:
如果一个游戏 G G G是由若干互不相干的游戏 g a m e 1 , g a m e 2 , . . . , g a m e k game_1,game_2,...,game_k game1,game2,...,gamek构成,玩家可以进入任何一个游戏并在这个游戏中操作一步,对于这种情况, S G ( G ) = S G ( g a m e 1 ) ⊕ S G ( g a m e 2 ) ⊕ . . . ⊕ S G ( g a m e k ) SG(G)=SG(game_1)\oplus SG(game_2)\oplus...\oplus SG(game_k) SG(G)=SG(game1)SG(game2)...SG(gamek)

UVA1378 - A Funny Stone Game

https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4124
这题可以把一个石子看作一个游戏, S G ( x ) SG(x) SG(x)表示第 x x x堆上的一个石子所构成的游戏,其后继局面就是第 j j j堆中的一个石子和第 k k k堆中的一个石子,而且这两个石子是互不相干的两个游戏,因此可以应用 S G SG SG定理来解决,枚举 j , k j,k j,k S G ( i ) = m e x i &lt; j ≤ k ( { S G ( j ) ⊕ S G ( k ) } ) SG(i) = mex_{i&lt;j\leq k}(\{SG(j)\oplus SG(k)\}) SG(i)=mexi<jk({SG(j)SG(k)})

#include <bits/stdc++.h>
#define maxn 2019
#define cl(x) memset(x,0,sizeof(x))
using namespace std;
typedef long long ll;
ll SG[maxn], s[maxn], tmp[maxn], N;
ll read(ll x=0)
{
	ll c, f=1;
	for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
	for(;isdigit(c);c=getchar())x=x*10+c-48;
	return f*x;
}
ll mex()
{
	ll i;
	for(i=0;i<maxn;i++)
		if(!tmp[i])return i;
}
bool judge()
{
	cl(SG);
	ll i, j, k, nim, x;
	for(i=N-1;i;i--)
	{
		cl(tmp);
		for(j=i+1;j<=N;j++)
			for(k=j;k<=N;k++)
				tmp[SG[j]^SG[k]] = 1;
		SG[i] = mex();
	}
	nim = 0;
	for(i=1;i<=N;i++)
	{
		nim ^= (~(s[i]&1)+1)&SG[i];
	}
	return !!nim;
}
int main()
{
	ll i, j, k, kase=0, a, b, c;
	while(N = read())
	{
		for(i=1;i<=N;i++)s[i] = read();
		a = b = c = 0;
		for(i=1;i<N and !a;i++)for(j=i+1;j<=N and !a;j++)for(k=j;k<=N and !a;k++)
		{
			if(s[i]>0)
			{
				s[i] --;
				s[j] ++;
				s[k] ++;
				if(judge()==0)a=i, b=j, c=k;
				s[i] ++;
				s[j] --;
				s[k] --; 
			}
		}
		kase++;
		printf("Game %lld: %lld %lld %lld\n",kase,a-1,b-1,c-1);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值