这个题目很有趣,有博弈知识,又有一点智商题的感觉。
题意为给你一段长为n的的线段。
两个游戏者轮流在一段长为2,未被染色的线段上涂色。
无法涂色的游戏者输。
题目有点灵活。关键在于怎么得到Sg函数值呢?
其实是这样的,对于一个长度为n的线段,我们枚举中间可能的连续的两个单位长度进行染色,然后判断是否存在一种染色使得染色后的状态为必败态就可以了。
不过要注意哦,染色后,原来的一段会变为两端(如果染色在端点,可以视其中一段为0),这样接下来的两端就需要分别染色了,所以根据博弈论的只是我们就知道,接下来的Sg函数值就是这两个长度所对应的Sg函数值的异或哦。然后用传统的Sg函数的Mex求法就可以了。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #define maxn 55 5 using namespace std; 6 7 int f[maxn],n,m,k; 8 bool b[maxn]; 9 10 void getF() 11 { 12 f[2]=1; 13 f[0]=f[1]=0; 14 for (int i=3; i<maxn; i++) 15 { 17 memset(b,false,sizeof b); 18 for (int j=1; j<=i-1; j++) 19 { 23 b[f[j-1]^f[i-j-1]]=true; 24 } 25 for (int j=0; ;j++) 26 if (!b[j]) 27 { 28 f[i]=j; 29 break; 30 } 31 } 32 } 33 34 int main() 35 { 36 getF(); 37 while (scanf("%d",&n)!=EOF) 38 { 39 m=0; 40 while (n--) scanf("%d",&k),m^=f[k]; 41 if (m) printf("Yes "); 42 else printf("No "); 43 } 44 return 0; 45 }