[HDU-5795]シンプルニムゲームニムゲームSGの演奏表関数は法律を見つけるために

[タイトル] トピックのリンク

二つのプレイヤーが作る.TO(何のお菓子を選んでいないが許可されていない)、nはヒープからキャンディーを選んで、最後の1は、彼らが同じヒープから来キャンディーの任意の数を選ぶことができgame.Onに各ターンを獲得するピックプレイヤーを交代しますそれらのそれぞれがミスをしたことがない場合は、プレイヤーがゲームに勝つかを調べるoperation.Pleaseゲームより面白い、プレイヤーは3つの小さな山(なし空のヒープ)の代わりに、ピッキングに1つのヒープを分離することができます。

InputIntputは、複数のテストケースが含まれています。最初の行は整数  1 T 100 1≤T≤100、テストケースの数。各ケースは整数で始まるN、ヒープの数を示し、次の行は、N個の整数含ま  S [ 0 ] S [ 1 ] S [ N - 1 ]、S [0]、[1]、...、S [N-1]とヒープ表すだ  Sを[ 0 ] S [ 1 ] S [ N - 1 ]、S [0]は、[1]〜S、...、S [N-1]それぞれのオブジェクト。1N1061 S [ I ] 10 9 (1≤n≤106,1≤s[I]≤109)OutputFor各テストケースは、出力「最初のプレイヤーが勝つのいずれかを含むwhickライン。 「または」第二のプレイヤーが「勝利。

サンプル入力

2
2
4 4
3
1 2 4

サンプル出力

第二のプレイヤーが勝ちます。
まずプレイヤーの勝利

を意味[タイトル]
同様のニム(nは石のヒープは、いくつかの山から石を取り除く2テイクターン)は、参加:(あなたが石を奪うことはできませんが、石は3つのグループに分けられ、各杭はできません空に)
正確にすべての石の勝利が完了した後に撮影したものです

[解説]
一般的な石がニムのゲームのn後継状態0〜N-1を重ね、すべての石のスタック数が0であるとの排他的論理和障害状態に運命にあります。
分割操作は、例えば、10から235までの分割は、実際には、後継者に相当2 ^ 3 ^ 4 = 5、後継者に対応する123に7ダウンが状態1 ^ 2 ^ 3 = 7述べ
7後続のすべてを状態^ 1 ^ 51 ^ 2 ^ 41 ^ 3 ^ 32 ^ 2 ^ 3 01234561
なしそれ(SG(X)=後続状態にSG関数の性質を持つテーブルを打ちます最小の自然数)
の観察をすることができる
SG(X-)= X- +。1(X-%==。8. 7)
SG(X-)= 1-X-%==。8(X-0)
SG(X-)= X-他

[SG]定理
Pポイント:失うポイント、限り、他の当事者間違いなく、失うとして、この点に位置プレーヤー
Nポイント:ポイントの勝利を、プレイヤーはこの点の上、限り、彼は間違いを持っていないとして、それは勝たなければならないされ
定理は:
1.すべてのポイントがまとめられていますPがポイントです。
2.関係なく動作、点Pは、勝利ポイントN.に失われる可能性が
3.任意の時点Nから点Pの負けを入力するには、少なくとも一つの方法を獲得します

MEX動作:
まず操作のセットに適用されるMEX(最小excludant)オペレーションを定義し、これは最小値を表す非負の整数の集合に属しません。
すなわち:MEX(S)=分{ X}、x∈N、x∉S
例えばMEX {0,1,2,4} = 3、MEX {2,3,5} = 0、MEX {}は= 0。

SG機能:

 

 

 定理1:

1.は、図の勝利ゲームに特定の状況がある場合は、ノードに対応する状況のSG関数の値が0より大きいがある場合にのみ。

ノードに対応する状況のSG関数の値がゼロに等しい場合にのみ図2は、ゲーム状況に運命。

定理2:

図構成されるゲームゲーム複数の有向グラフとSGゲーム関数値がゼロでないある場合にのみ場合、勝つ{GiがN}があります。

 

 

[コード]プレイテーブル

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int g[1010];
 4 void init() {
 5     memset(g, -1, sizeof(g));
 6 }
 7 int getSG(int x) {
 8     if(g[x] != -1) return g[x];
 9     if(x == 0) return 0;
10     if(x == 1) return 1;
11     if(x == 2) return 2;
12     int vis[110];
13     memset(vis, 0, sizeof(vis));
14     for(int i = 1; i < x; i++) {
15         int t = 0;
16         int a = getSG(i);
17         vis[a] = 1;
18         for(int j = 1; j < x - i; j++) {
19             int b = getSG(j);
20             int c = getSG(x - i - j);
21             vis[a^b^c] = 1;
22         }
23     }
24     vis[0] = 1;
25     for(int i = 0; ; i++) if(!vis[i])
26         return g[x] = i;
27 }
28 int main() {
29     int n;
30     init();
31     for(int i = 1; i <= 100; i++) {
32         g[i] = getSG(i);
33         printf("%d %d %d\n", i, i % 8, g[i]);
34     }
35 }

【AC代码】

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 int getsg(int x){
 4     if(x%8==0)return x-1;
 5     if(x%8==7)return x+1;
 6     return x;
 7 }
 8 int main(){
 9     int t,n,c,ans;
10     scanf("%d",&t);
11     while(t--){
12         ans=0;
13         scanf("%d",&n);
14         for(int i=1;i<=n;i++){
15             scanf("%d",&c);
16             ans^=getsg(c);
17         }
18         if(ans)printf("First player wins.\n");
19         else printf("Second player wins.\n");
20     }
21     return 0;
22 }

おすすめ

転載: www.cnblogs.com/conver/p/12200745.html