两堆石子,每次可以将较多的一堆减去较少的一堆数量的整倍数,取走最后一个石子的胜利。现在要同时进行N个相同的游戏,取走最后一颗石子的胜利,求先手胜负。
这题和原来的题不一样的一点就是同时进行多个游戏,即每次操作要在所有还没有结束的局面中进行操作,而游戏的胜负是由最后结束的一个游戏的胜负决定的,2009年国家集训队论文 贾志豪:《组合游戏略述——浅谈SG游戏的若干拓展及变形》里对这种游戏进行了讨论,主体思路就是必胜的局面尽可能拖到最后结束,必败的局面尽量优先结束,这样最后只要判断步数最长的游戏的胜负即可判断整个游戏的胜负。这题思路也是类似,要注意的一点是x/y>1时的讨论,如果某个玩家掌握了这一局面,那么这轮肯定会赢了,因为无论是抢下一个x.y>1或者是抢最后一个石子,我方都可以根据需要决定之后状态的奇偶性,所以结合这一点,在结合上面尽量延长必胜局的方案这题就ok了。
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstring>
using namespace std;
typedef long long ll;
int f[1010];
int n,m,k;
int main()
{
// freopen("in.txt","r",stdin);
while(~scanf("%d",&n))
{
int ans=0,x,y;
int cnt=0;
for (int i=1; i<=n; i++)
{
scanf("%d%d",&x,&y);
if (x<y) swap(x,y);
f[1]=x; f[2]=y;
cnt=2;
while(f[cnt])
{
f[cnt+1]=f[cnt-1]%f[cnt];
++cnt;
}
int j=-1,sp=0;
for (int i=1; i<cnt-1; i++)
{
if (f[i]/f[i+1]>1)
{
if (j>0 && j%2!=i%2) sp++;
j=i;
}
}
ans=max(ans,sp+cnt);
}
if (ans&1) puts("MM");
else puts("GG");
}
return 0;
}
本文探讨了组合游戏中多个游戏同时进行的情况,详细解释了如何通过延长必胜局面来判断整体游戏的胜负。重点分析了x/y>1时的讨论策略,并提供了具体的实现代码。
1587

被折叠的 条评论
为什么被折叠?



