• 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
    ",i-2,j-2,k-2);
    69         else printf("-1 -1 -1
    ");
    70     }
    71     return 0;
    72 }
  • 相关阅读:
    【2019-08-03】自卑和悲观是有区别的
    你现在不用写代码了吧?
    【2019-08-02】信任是一种能力
    【2019-08-01】给孩子一个渴望长大的榜样
    【一句日历】2019年8月
    【2019-07-31】一切皆有寓意
    【2019-07-30】原来努力会上瘾
    【2019-07-29】睡多了,会被宰的
    【2019-07-28】活到老,学到老
    【2019-07-27】习惯的力量很强大
  • 原文地址:https://www.cnblogs.com/zarth/p/6718579.html
Copyright © 2020-2023  润新知