标签:nim or not nim hdu3032 sg函数 博弈 数论
小k,终于忍不住了。。。正在笔记本上装win10,有点小激动。
Description
Input
Output
Sample Input
2 3 2 2 3 2 3 3
Sample Output
Alice Bob
题意:Alice和Bob轮流取N堆石子,每堆S[i]个,Alice先,每一次可以从任意一堆中拿走任意个石子,也可以将一堆石子分为两个小堆。先拿完者获胜。
数据范围: (1 ≤ N ≤ 10^6, 1 ≤ S[i] ≤ 2^31 - 1).
思路: 此题为博弈中的-----取走-分割游戏(这种游戏允许取走某些东西,然后将原来的一个游戏分成若干个相同的游戏)
由于数据范围,不能直接求sg值只能打表找规律;
有SJ 定理:
对于任意的一个 Anti-SG 游戏,如果我们规定当局面中所有单一游戏的 SG 值为 0 时游戏 结束,则先手必胜当且仅当以下两个条件满足任意一个:
(1)游戏的 SG 函数不为 0,且游戏中某个单一游戏的 SG 函数大于1。
(2)游戏的 SG 函数为 0,且游戏中没有单一游戏的 SG 函数大于 1。
Lasker‘s Nim游戏:每一轮允许两会中操作之一:①、从一堆石子中取走任意多个,②、将一堆数量不少于2的石子分成都不为空的两堆。
分析:很明显:sg(0) = 0,sg(1) = 1。
状态2的后继有:0,1和(1,1),他们的SG值分别为0,1,0,所以sg(2) =2。
状态3的后继有:0、1、2、(1,2),他们的SG值分别为0、1、2、3,所以sg(3) = 4。
状态4的后继有:0、1、2、3、(1,3)和(2,2),他们的SG值分别为0,1,2,4,5,0,所以sg(4) = 3.
再推一些,推测得到:对于所有的k >= 0,有 sg( 4k+1 ) = 4k+1; sg( 4k+2 ) = 4k+2; sg( 4k+3 ) = 4k+4; sg( 4k+4 ) = 4k+3。
假设游戏初始时有3堆,分别有2、5和7颗石子。三堆的SG函数值分别为2、5、8,他们的Nim和等于15.所以要走到P状态,就要使得第三堆的SG值变成7,可以将第三对按1和6分成两堆。
打表:
#include<stdio.h>
#include<string.h>
int sg[10000];
void init()//sg打表
{
// memset(sg,0,sizeof(sg));
sg[0]=0;
sg[1]=1;
for(int i=2;i<=1000;i++)
{
bool vis[1010]={false};
for(int j=0;j<=i;j++)
{
vis[sg[j]]=true;//取石子
if(j!=0&&j!=i)vis[sg[j]^sg[i-j]]=true;//拆分
}
int j=0;
while(vis[j]!=0)j++;
sg[i]=j;
}
}
int main()
{
// memset(sg,-1,sizeof(sg));
init();
for(int i=1;i<=1000;i++)
{
printf("%d\t",sg[i]);
if(i%4==0)printf("\n");
}
}
规律还不是很明显,那么看下一张;
发现规律:当x%4==0时sg[x]=x-1;当x%4==3时sg[x]=x+1;
其余sg[x]=x。然后异或下就出来结果了。主要还是用学会SG定理。
那么就来编程吧,
转载请注明出处:寻找&星空の孩子
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int find_sg(int x)
{
if(x%4==0)return x-1;
else if(x%4==3)return x+1;
return x;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int a,n,i,j,ans=0;
scanf("%d",&n);
for(i=0;i<n;i++)
{
scanf("%d",&a);
ans=ans^find_sg(a);
}
if(ans==0)printf("Bob\n");
else printf("Alice\n");
}
return 0;
}
版权声明:本文为博主原创文章,未经博主允许不得转载。
Nim or not Nim?(hdu3032+SG函数)取走-分割游戏,经典
标签:nim or not nim hdu3032 sg函数 博弈 数论
原文地址:http://blog.csdn.net/u010579068/article/details/47356699