bzoj 1188 : [HNOI2007]分裂游戏 sg函数

题目链接

给n个位置, 每个位置有一个小球。 现在两个人进行操作, 每次操作可以选择一个位置i, 拿走一个小球。然后在位置j, k(i<j<=k)处放置一个小球。 问你先进行什么操作会先手必胜以及方法数量。

感觉这题好神

如果一个位置有偶数个小球, 那么等价于这个位置没有小球。 因为第二个人可以进行和第一个人相同的操作。 所以初始值%2。

然后我们把每个位置看成一个状态, 如果i有一个小球, 等价于j, k 也有一个小球。 然后转移。

方法数量就n^3枚举就可以了。

#include <bits/stdc++.h>
using namespace std;
#define mem1(a) memset(a, -1, sizeof(a))int sg[22], a[22], n;
int mex(int x)
{
    if(~sg[x])
        return sg[x];
    bool vis[1000];
    memset(vis, 0, sizeof(vis));
    for(int i = x + 1; i <= n; i++) {
        for(int j = i; j <= n; j++) {
            vis[mex(i)^mex(j)] = 1;
        }
    }
    for(int i = 0; ; i++) {
        if(!vis[i])
            return sg[x] = i;
    }
}
int main()
{
    int t;
    cin>>t;
    while(t--) {
        cin>>n;
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
        }
        mem1(sg);
        int ans = 0, cnt = 0;
        for(int i = 1; i <= n; i++) {
            if(a[i]&1) {
                ans ^= mex(i);
            }
        }
        int flag = 0;
        for(int i = 1; i <= n; i++) {
            for(int j = i + 1; j <= n; j++) {
                for(int k = j; k <= n; k++) {
                    ans ^= mex(i)^mex(j)^mex(k);
                    if(!flag && ans == 0) {
                        printf("%d %d %d\n", i-1, j-1, k-1);
                        flag = 1;
                    }
                    if(ans == 0) {
                        cnt++;
                    }
                    ans ^= mex(i)^mex(j)^mex(k);
                }
            }
        }
        if(cnt != 0)
            cout<<cnt<<endl;
        else {
            printf("-1 -1 -1\n0\n");
        }

    }
    return 0;
}
时间: 2024-10-23 07:04:17

bzoj 1188 : [HNOI2007]分裂游戏 sg函数的相关文章

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

1188: [HNOI2007]分裂游戏 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 733  Solved: 451[Submit][Status][Discuss] Description 聪 聪和睿睿最近迷上了一款叫做分裂的游戏. 该游戏的规则试: 共有 n 个瓶子, 标号为 0,1,2.....n-1, 第 i 个瓶子中装有 p[i]颗巧克力豆,两个人轮流取豆子,每一轮每人选择 3 个瓶子.标号为 i,j,k, 并要保证 i < j ,

[BZOJ 1188] [HNOI2007] 分裂游戏 【博弈论|SG函数】

题目链接:BZOJ - 1188 题目分析 我们把每一颗石子看做一个单个的游戏,它的 SG 值取决于它的位置. 对于一颗在 i 位置的石子,根据游戏规则,它的后继状态就是枚举符合条件的 j, k.然后后继状态就是 j 与 k 这两个游戏的和. 游戏的和的 SG 值就是几个单一游戏的 SG 值的异或和. 那么还是根据 SG 函数的定义 , 即 SG(u) = mex(SG(v)) ,预处理求出每个位置的 SG 值.一个位置的 SG 值与它后面的位置有关,是取决于它是倒数第几个位置,那么我们预处理求

BZOJ 1188: [HNOI2007]分裂游戏(multi-nim)

Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1386  Solved: 840[Submit][Status][Discuss] Description 聪聪和睿睿最近迷上了一款叫做分裂的游戏.该游戏的规则试:共有n个瓶子,标号为0,1,2.....n-1,第i个瓶子中 装有p[i]颗巧克力豆,两个人轮流取豆子,每一轮每人选择3个瓶子.标号为i,j,k,并要保证i<j,j<=k且第i个瓶子 中至少要有1颗巧克力豆,随后这个人从第i个瓶子中拿走

BZOJ P1188 HNOI2007 分裂游戏——solution

题目描述: (<--这个) 组合游戏,——把每个石头看做一个游戏, Multi_game——消去i上的石子后,,k上的游戏又多了一个: 于是就套用multi_game的模型即可 求解SG函数时,发现一个游戏的后继是谁只与其位置有关,于是可以用一个SG值代替一堆游戏的SG值: 求解完所有SG值,后异或即可: 代码: 1 #include<cstdio> 2 #include<cstring> 3 using namespace std; 4 int a[25],n,sg[25]

组合游戏 - SG函数和SG定理

在介绍SG函数和SG定理之前我们先介绍介绍必胜点与必败点吧. 必胜点和必败点的概念: P点:必败点,换而言之,就是谁处于此位置,则在双方操作正确的情况下必败. N点:必胜点,处于此情况下,双方操作均正确的情况下必胜. 必胜点和必败点的性质: 1.所有终结点是 必败点 P .(我们以此为基本前提进行推理,换句话说,我们以此为假设) 2.从任何必胜点N 操作,至少有一种方式可以进入必败点 P. 3.无论如何操作,必败点P 都只能进入 必胜点 N. 我们研究必胜点和必败点的目的时间为题进行简化,有助于

BZOJ 1874: [BeiJing2009 WinterCamp]取石子游戏 [Nim游戏 SG函数]

小H和小Z正在玩一个取石子游戏. 取石子游戏的规则是这样的,每个人每次可以从一堆石子中取出若干个石子,每次取石子的个数有限制,谁不能取石子时就会输掉游戏. 小H先进行操作,他想问你他是否有必胜策略,如果有,第一步如何取石子. N≤10 Ai≤1000 裸SG函数啊 然而我连SG函数都不会求了,WA了一会儿之后照别人代码改发现vis公用了... #include <iostream> #include <cstdio> #include <cstring> #includ

BZOJ 1874: [BeiJing2009 WinterCamp]取石子游戏(SG函数)

Time Limit: 5 Sec  Memory Limit: 162 MBSubmit: 871  Solved: 365[Submit][Status][Discuss] Description 小H和小Z正在玩一个取石子游戏. 取石子游戏的规则是这样的,每个人每次可以从一堆石子中取出若干个石子, 每次取石子的个数有限制,谁不能取石子时就会输掉游戏. 小H先进行操作,他想问你他是否有必胜策略,如果有 ,第一步如何取石子. Input 输入文件的第一行为石子的堆数N 接下来N行,每行一个数A

Bzoj1188 [HNOI2007]分裂游戏

Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1110  Solved: 679 Description 聪聪和睿睿最近迷上了一款叫做分裂的游戏. 该游戏的规则试: 共有 n 个瓶子, 标号为 0,1,2.....n-1, 第 i 个瓶子中装有 p[i]颗巧克力豆,两个人轮流取豆子,每一轮每人选择 3 个瓶子.标号为 i,j,k, 并要保证 i < j , j < = k 且第 i 个瓶子中至少要有 1 颗巧克力豆,随后这个人从第 i 个瓶子中

Wannafly挑战赛23 T2游戏 SG函数

哎,被卡科技了,想了三个小时,最后还是大佬给我说是\(SG\)函数. \(SG\)函数,用起来很简单,证明呢?(不可能的,这辈子都是不可能的) \(SG\)定理 游戏的\(SG\)函数就是各个子游戏的\(SG\)函数的\(Nim-sum\)(就是异或和),比如多堆石子的\(SG\)函数就是所有单堆石子\(SG\)函数的异或和. \(SG\)函数 首先定义\(mex(T)\)为\(T\)中未出现的自然数中最小的数,其中\(T \subset N\),如\(mex(0,2,3)=1\),\(mex(