H - Nim or not Nim? HDU - 3032

 

 【题目意思】:

  如图。

【思路】:

  第一次遇到哈,学习一手。    博弈论进阶之Multi-SG - 自为风月马前卒 - 博客园 (cnblogs.com)

  Multi-Nim 型题目。

  它的定义是这样的:有nn堆石子,两个人可以从任意一堆石子中拿任意多个石子(不能不拿)或把一堆数量不少于2颗石子分为两堆不为空的石子堆,没法拿的人失败。问谁会胜利。

  第一个操作从堆中拿出石子是常见的nim游戏。

  第二个操作 将堆分成两堆 , 其实是变成两次nim游戏 。

  根据 sg 的 原理 ,我们可以把分成的两次游戏看成当前游戏的一次后继 , 所以 当前游戏的sg(x) = sg(0,1,2,3,。。。,x-1,sg(y1,y2),sg(y3,y4)......)。

  例子 :

    如果当前的x等于5 

  sg[5] = mex(         sg[0]     , sg[1]     , sg[2]      ,sg[3]      , sg[4]      , sg({1,4})       ,  sg({2,3})       ) .

  sg({2,3}) = sg(2)^sg(3) ;

 

  

  另外这种游戏还有一个非常神奇的性质

         x-1    ( x%4 ==0 )

  SG(x) =    x        ( x%4 ==1 || x%4==2 )

        x+1    ( x%4 == 3 )

  然后把这个结论背过就好啦233

 

 

 

  根据上面的游戏,我们定义Multi-SG游戏

 

    •   Multi-SG 游戏规定,在符合拓扑原则的前提下,一个单一游戏的后继可以为多个单一游戏
    •   Multi-SG其他规则与SG游戏相同。

 

  注意在这里要分清楚后继多个单一游戏

 

  对于一个状态来说,不同的划分方法会产生多个不同的后继,而在一个后继中可能含有多个独立的游戏

 

  一个后继状态的SG值即为后继状态中独立游戏的异或和

 

  该状态的SG值即为后继状态的SG值中未出现过的最小值

【代码】:

  

#include <bits/stdc++.h>
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <bitset>
#include <cstdlib>
#include <cmath>
#include <set>

#define ms(a, b) memset(a,b,sizeof(a))
#define fast ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define ll long long
#define ull unsigned long long
#define rep(i, a, b)  for(ll i=a;i<=b;i++)
#define lep(i, a, b)  for(ll i=a;i>=b;i--)
#define endl '\n'
#define pii pair<int, int>
#define pll pair<ll, ll>
#define vi  vector<ll>
#define vpi vector<pii>
#define vpl vector<pll>
#define mi  map<ll,ll>
#define all(a)  (a).begin(),(a).end()
#define gcd __gcd
#define pb push_back
#define mp make_pair
#define lb lower_bound
#define ub upper_bound

#define ff first
#define ss second
#define test4(x, y, z, a) cout<<"x is "<<x<<"        y is "<<y<<"        z is "<<z<<"        a is "<<a<<endl;
#define test3(x, y, z) cout<<"x is "<<x<<"        y is "<<y<<"        z is "<<z<<endl;
#define test2(x, y) cout<<"x is "<<x<<"        y is "<<y<<endl;
#define test1(x) cout<<"x is "<<x<<endl;
using namespace std;
const int N = 1e5 + 10;
const int maxx = 0x3f3f3f;
const int mod = 1e9 + 7;
const int minn = -0x3f3f3f;
const int M = 2 * N;
ll T, n, m;
ll a[N];
int sg(int x ){
    if ( x%4==0 )   return x-1 ;
    if ( x%4==3 )   return x+1 ;
    return x;
}
void solve() {
    cin>>n;
    int res = 0 ;
    rep(i,1,n){
        cin>> a[i] ;
        res ^= sg(a[i]);
    }
    if ( res )  cout<<"Alice"<<endl;
    else cout<<"Bob"<<endl;
}

int main() {
    fast;
    cin >> T;
    while (T--) {
        solve();
    }
    return 0;
}
View Code

 

posted @ 2022-04-10 20:34  Pan_c  阅读(69)  评论(0)    收藏  举报