YBTOJ魔法珠(博弈论)

这篇博客探讨了一种将经典博弈论问题NIM转化为有向图游戏的方法。通过建立根节点和叶节点的关系,将局面转换成图结构,并利用SG函数判断游戏的胜负状态。AC代码展示了如何实现这一转换并进行求解。文章深入浅出地解释了博弈论中的异或操作和子局面分析,为理解复杂博弈问题提供了新的视角。

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

YBTOJ魔法珠(博弈论)

在这里插入图片描述

这道题是NIM游戏和有向图游戏结合的博弈论问题。题面咋一看这就是个NIM游戏,怎么把它转到有向图游戏呢?我们假设NIM游戏中一个大的局面为一个根节点,然后所有小的子局面为叶节点,这样,NIM游戏就转化为了有向图游戏。最后我们根据NIM相关定理可得:SG(1)SG(2)……^SG(n)=0则先手必败,反之先手必胜。求SG函数部分具体看代码注释。
AC代码:

#include<bits/stdc++.h>
using namespace std;
int n,x,sg[1010],ans;
inline int SG(int x)
{
	if(sg[x]!=-1)return sg[x];
	int y=0;
	for(int i=1;i*i<=x;++i) if(!(x%i)) {if(i!=x) y^=SG(i); if(i*i!=x&&i!=1) y^=SG(x/i);}//先求出所有子局面异或和
	bool ch[1010]; memset(ch,0,sizeof(ch));
	for(int i=1;i*i<=x;++i) if(!(x%i)) {if(i!=x) ch[SG(i)^y]=1; if(i*i!=x&&i!=1) ch[SG(x/i)^y]=1;}//枚举每一种子局面,y^SG(i)即表示消去第i堆
	while(ch[++sg[x]]);//统计答案
	return sg[x];
}
int main()
{
	for(int i=1;i<=1000;++i)sg[i]=-1;
	while(scanf("%d",&n)!=EOF)
	{
		ans=0;
		while(n--) scanf("%d",&x),ans^=SG(x);
		printf(ans?("freda\n"):("rainbow\n"));
	}
	return 0;
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值