UVALive 3668 A Funny Stone Game

Posted 莫兹ACM

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了UVALive 3668 A Funny Stone Game相关的知识,希望对你有一定的参考价值。

题目链接:UVALive - 3668

题目大意为给定n堆石子,每次的操作是选择三个数i<j<=k,从i中拿一枚石子,在j和k中分别放入一枚石子。不能操作者输。求先手是否能赢,若可以,则输出字典序最小的第一步操作。

思路是把在每个位置上的每颗石子当成一个游戏。

用SG[i]表示在第i堆中的一颗石子的sg函数。

则SG[i]=mex(SG[j] ^ SG[k])。

然后异或求游戏的和即可。

为找到字典序最小的第一步操作,我们枚举第一步操作,然后求游戏的和即可。

 

代码如下:

 1 #include"cstdio"
 2 #include"iostream"
 3 #include"cstring"
 4 #include"algorithm"
 5 #include"cstdlib"
 6 #include"vector"
 7 #include"set"
 8 #include"map"
 9 #include"cmath"
10 using namespace std;
11 typedef long long LL;
12 const LL MAXN=30;
13 
14 int n;
15 int f[MAXN];
16 int sg(int x)
17 {
18     if(x==n) return 0;
19     if(f[x]!=-1) return f[x];
20     int vis[200];
21     memset(vis,0,sizeof(vis));
22     for(int i=x+1;i<=n;i++)
23         for(int j=i;j<=n;j++)
24             vis[sg(i)^sg(j)]=1;
25     for(int i=0;i<200;i++)
26         if(!vis[i])
27             return f[x]=i;
28     return 200;
29 }
30 int d[MAXN];
31 int cal()
32 {
33     memset(f,-1,sizeof(f));
34     int ans=0;
35     for(int i=1;i<=n;i++)
36         if(d[i]%2!=0)
37             ans ^= sg(i);
38     return ans;
39 }
40 int main()
41 {
42 #ifdef LOCAL
43     freopen("in.txt","r",stdin);
44     // freopen("out.txt","w",stdout);
45 #endif
46     int t=0;
47     while(scanf("%d",&n)!=EOF && n)
48     {
49         for(int i=1;i<=n;i++)
50             scanf("%d",&d[i]);
51         int i,j,k;
52         bool ok=false;
53         for(i=1;!ok && i<=n;i++)
54             for(j=i+1;!ok && j<=n;j++)
55                 for(k=j;!ok && k<=n;k++)
56                     if(d[i]>0)
57                     {
58                         d[i]--;
59                         d[j]++;
60                         d[k]++;
61                         if(cal()==0)
62                             ok=true;
63                         d[i]++;
64                         d[j]--;
65                         d[k]--;
66                     }
67         printf("Game %d: ",++t);
68         if(ok) printf("%d %d %d\n",i-2,j-2,k-2);
69         else printf("-1 -1 -1\n");
70     }
71     return 0;
72 }

 

以上是关于UVALive 3668 A Funny Stone Game的主要内容,如果未能解决你的问题,请参考以下文章

Pollard rho算法+Miller Rabin算法 BZOJ 3668 Rabin-Miller算法

POJ 2484 A Funny Game(找规律)

POJ 2599 A funny game#树形SG(DFS实现)

poj 2484 A Funny Game

POJ 2484 A Funny Game(智商博弈)

POJ 2484 A Funny Game