1188: [HNOI2007]分裂游戏

Time Limit: 10 Sec  Memory Limit: 162 MB
Submit: 973  Solved: 599
[Submit][Status][Discuss]

Description

聪聪和睿睿最近迷上了一款叫做分裂的游戏。 该游戏的规则试: 共有 n 个瓶子, 标号为 0,1,2.....n-1, 第 i 个瓶子中装有 p[i]颗巧克力豆,两个人轮流取豆子,每一轮每人选择 3 个瓶子。标号为 i,j,k, 并要保证 i < j , j < = k 且第 i 个瓶子中至少要有 1 颗巧克力豆,随后这个人从第 i 个瓶子中拿走一颗豆 子并在 j,k 中各放入一粒豆子(j 可能等于 k) 。如果轮到某人而他无法按规则取豆子,那么他将输 掉比赛。胜利者可以拿走所有的巧克力豆! 两人最后决定由聪聪先取豆子,为了能够得到最终的巧克力豆,聪聪自然希望赢得比赛。他思考 了一下,发现在有的情况下,先拿的人一定有办法取胜,但是他不知道对于其他情况是否有必胜 策略,更不知道第一步该如何取。他决定偷偷请教聪明的你,希望你能告诉他,在给定每个瓶子 中的最初豆子数后是否能让自己得到所有巧克力豆,他还希望你告诉他第一步该如何取,并且为 了必胜,第一步有多少种取法? 假定 1 < n < = 21,p[i] < = 10000

Input

输入文件第一行是一个整数t表示测试数据的组数,接下来为t组测试数据(t<=10)。每组测试数据的第一行是瓶子的个数n,接下来的一行有n个由空格隔开的非负整数,表示每个瓶子中的豆子数。

Output

对于每组测试数据,输出包括两行,第一行为用一个空格两两隔开的三个整数,表示要想赢得游戏,第一步应该选取的3个瓶子的编号i,j,k,如果有多组符合要求的解,那么输出字典序最小的一组。如果无论如何都无法赢得游戏,那么输出用一个空格两两隔开的三个-1。第二行表示要想确保赢得比赛,第一步有多少种不同的取法。

Sample Input

2
4
1 0 1 5000
3
0 0 1

Sample Output

0 2 3
1
-1 -1 -1
0

HINT

 

Source

 

[Submit][Status][Discuss]

----------------------------------------------------------------

今天终于理解sg函数怎么用的了

百度百科上讲的挺好的 链接

这道题应该算基础的了

每个格子都有自己的sg值

sg[i]=mex{sg[j]^sg[k] (i<j<=k)}

因为在i节点上的豆子 只能到达两个比i大的节点

所以就化为了两个子游戏 两个子游戏的xor值就是一种后继状态

然后对于每个节点上的豆子 都xor上答案(如果有偶数个就不用了 奇数个就xor一次就好了 反正剩下的都会抵消)如果答案是0就代表必败

然后n3枚举任意一个节点的豆子到另外两个节点 如果能让答案变成 0就是一种方案

后来写完后发现sg可以预处理 但没什么关系

代码:

#include<cstdio>
#define For(i,x,y) for(i=x;i<=y;++i)
#define Forn(i,x,y) for(i=x;i>=y;--i)
int sg[];bool vis[];bool p[];int i,j,k,gg,t;
void work(){
    int n;scanf("%d",&n);
    sg[n-]=;
    Forn(i,n-,)
    {
        For(gg,,)vis[gg]=;
        For(j,i+,n-)
        {
            For(k,j,n-)
            {
                vis[sg[j]^sg[k]]=;
            }
        }
        For(t,,){
            if(!vis[t]){sg[i]=t;break;}
        }
    }
    int res=;
    For(i,,n-){
        int x;scanf("%d",&x);
        if(x&)res^=sg[i];
        p[i]=x;
    }
    bool flg=;int fangan=;
        For(i,,n-)
        {
            if(p[i]==)continue;
            For(j,i+,n-)
            {
                For(k,j,n-)
                {      
                    if((res^sg[i]^sg[j]^sg[k])==){
                        fangan++;if(!flg){
                            printf("%d %d %d",i,j,k);
                            flg=;
                        }
                    }  
                }
            }
        }
    if(!fangan)printf("-1 -1 -1");
        printf("\n%d",fangan);
    puts("");
}
int main(){
    int T;scanf("%d",&T);
    while(T--)
        work();
}

bzoj1188 [HNOI2007]分裂游戏 博弈论 sg函数的应用的更多相关文章

  1. bzoj 1188 [HNOI2007]分裂游戏(SG函数,博弈)

    1188: [HNOI2007]分裂游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 733  Solved: 451[Submit][Status ...

  2. BZOJ1188:[HNOI2007]分裂游戏(博弈论)

    Description 聪聪和睿睿最近迷上了一款叫做分裂的游戏.该游戏的规则试:共有n个瓶子,标号为0,1,2.....n-1,第i个瓶子中装有p[i]颗巧克力豆,两个人轮流取豆子,每一轮每人选择3个 ...

  3. BZOJ1188 [HNOI2007]分裂游戏(SG函数)

    传送门 拿到这道题就知道是典型的博弈论,但是却不知道怎么设计它的SG函数.看了解析一类组合游戏这篇论文之后才知道这道题应该怎么做. 这道题需要奇特的模型转换.即把每一个石子当做一堆石子,且原来在第i堆 ...

  4. [bzoj1188][HNOI2007]分裂游戏_博弈论

    分裂游戏 bzoj-1188 HNOI-2007 题目大意:题目链接. 注释:略. 想法: 我们发现如果一个瓶子内的小球个数是奇数才是有效的. 所以我们就可以将问题变成了一个瓶子里最多只有一个球球. ...

  5. [BZOJ1188][HNOI2007]分裂游戏(博弈论)

    题目:http://www.lydsy.com:808/JudgeOnline/problem.php?id=1188 分析: 设SG[i]表示一个石子在位置i上的SG值 这个很容易暴力求,因为i的后 ...

  6. [2016北京集训试题6]魔法游戏-[博弈论-sg函数]

    Description Solution 首先,每个节点上的权值可以等价于该节点上有(它的权的二进制位数+1)个石子,每次可以拿若干个石子但不能不拿. 然后就发现这和NIM游戏很像,就计算sg函数em ...

  7. 【GZOI2015】石子游戏 博弈论 SG函数

    题目大意 有\(n\)堆石子,两个人可以轮流取石子.每次可以选择一堆石子,做出下列的其中一点操作: 1.移去整堆石子 2.设石子堆中有\(x\)个石子,取出\(y\)堆石子,其中\(1\leq y&l ...

  8. 【博弈论】【SG函数】【枚举】bzoj1188 [HNOI2007]分裂游戏

    因为第i个瓶子里的所有豆子都是等价的,设sg(i)表示第i个瓶子的sg值,可以转移到sg(j)^sg(k)(i<j<n,j<=k<n)的状态. 只需要考虑豆子数是奇数的瓶子啦, ...

  9. bzoj1188: [HNOI2007]分裂游戏

    Description 聪聪和睿睿最近迷上了一款叫做分裂的游戏. 该游戏的规则试: 共有 n 个瓶子, 标号为 0,1,2.....n-1, 第 i 个瓶子中装有 p[i]颗巧克力豆,两个人轮流取豆子 ...

随机推荐

  1. POJ 题目1141 Brackets Sequence(区间DP记录路径)

    Brackets Sequence Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 27793   Accepted: 788 ...

  2. auto_ptr源码剖析

    /* * Copyright (c) 1997-1999 * Silicon Graphics Computer Systems, Inc. * * Permission to use, copy, ...

  3. C# FTP/SFTP文件传输控件FTP for .NET/.NET CF 详细介绍

    FTP for .NET将FTP客户端功能添加到您的应用程序之中..NET控件的FTP支持所有常用的FTP服务器以及代理服务器,包括可扩展的目录解析.同步以及异步操作.主动与被动模式.以VB.NET与 ...

  4. goldengate for big data 12.2.0.1.1新增功能

    新格式支持:包括Avro OCF和HDFS顺序文件,OGG现在支持将数据写入Avro对象容器(Object container format)和HDFS顺序文件 支持Hadoop平台元数据或DDL更新 ...

  5. #define用法解析

    #define Add(a,b) a+b; 在一般使用的时候是没有问题的,但是如果遇到如: c * Add(a,b) * d 的时候就会出现问题,代数式的本意是a+b然后去和c,d相乘,但是因为使用了 ...

  6. 大视野3562 [SHOI2014]神奇化合物

    http://www.lydsy.com/JudgeOnline/problem.php?id=3562 //Accepted 6020 kb 1012 ms //由于题目的特殊要求:然而,令科学家们 ...

  7. NOIP 考前 并查集复习

    POJ 1182 把一个点拆成x,x+n,x+2*n,x吃y可以表示认为x,y+n是一类的,x+n,y+2*n是一类,x+2*n,y是一类. #include <cstdio> ; ],n ...

  8. java经典题目

    /***********Ryear.java begin********************/ import java.util.Scanner;public class Ryear { /** ...

  9. python27(32位)安装模块报错“error: Unable to find vcvarsall.bat”

    1)首先,下载一个Microsoft Visual C++ Compiler for Python 2.7的补丁,下载地址在这里: http://www.microsoft.com/en-us/dow ...

  10. 利用win服务定时为网卡启用/禁用

    上周,Boss和我说,他儿子夜里爬起来用笔记本在被窝里玩CF,问路由器可以解决么,我看了是TPLINK的普通家用无线路由器,不支持禁用CF客户端网游,可以通过配置端口屏蔽什么的,但是白天又要开启,想想 ...