1. 程式人生 > 其它 >H - Nim or not Nim? HDU - 3032

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