ZOJ2083_Win the Game

这个题目很有趣,有博弈知识,又有一点智商题的感觉。

题意为给你一段长为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 }
如有转载,请注明出处(http://www.cnblogs.com/lochan)
原文地址:https://www.cnblogs.com/lochan/p/3376643.html