标签: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