1. 程式人生 > >1022: [SHOI2008]小約翰的遊戲John9(Auti_SG)

1022: [SHOI2008]小約翰的遊戲John9(Auti_SG)

style log script 一行 組成 spa std Go turn

1022: [SHOI2008]小約翰的遊戲John

Time Limit: 1 Sec Memory Limit: 162 MB
Submit: 3150 Solved: 2013
[Submit][Status][Discuss]

Description

  小約翰經常和他的哥哥玩一個非常有趣的遊戲:桌子上有n堆石子,小約翰和他的哥哥輪流取石子,每個人取
的時候,可以隨意選擇一堆石子,在這堆石子中取走任意多的石子,但不能一粒石子也不取,我們規定取到最後一
粒石子的人算輸。小約翰相當固執,他堅持認為先取的人有很大的優勢,所以他總是先取石子,而他的哥哥就聰明
多了,他從來沒有在遊戲中犯過錯誤。小約翰一怒之前請你來做他的參謀。自然,你應該先寫一個程序,預測一下

誰將獲得遊戲的勝利。

Input

  本題的輸入由多組數據組成第一行包括一個整數T,表示輸入總共有T組數據(T≤500)。每組數據的第一行包
括一個整數N(N≤50),表示共有N堆石子,接下來有N個不超過5000的整數,分別表示每堆石子的數目。

Output

  每組數據的輸出占一行,每行輸出一個單詞。如果約翰能贏得比賽,則輸出“John”,否則輸出“Brother”
,請註意單詞的大小寫。

Sample Input

2
3
3 5 1
1
1

Sample Output

John
Brother

code

sj定理: 先手必勝當且僅當:(1)遊戲的SG函數不為0且遊戲中某個單一遊戲的SG函數大於1;(2)遊戲的SG函數為0且遊戲中沒有單一遊戲的SG函數大於1。

 1 #include<cstdio>
 2 #include<algorithm>
 3 
 4 using namespace std;
 5 int f[5010];
 6 //sg[i] = i;
 7 int main () {
 8     int T,n;
 9     scanf("%d",&T);
10     for (int Case=1; Case<=T; ++Case) {
11 scanf("%d",&n); 12 bool flag = false; 13 int ans = 0; 14 for (int t,i=1; i<=n; ++i) { 15 scanf("%d",&t); 16 ans ^= t; 17 if (t > 1) flag = true; 18 } 19 if ((ans==0&&!flag)||(ans!=0&&flag)) puts("John"); 20 else puts("Brother"); 21 } 22 return 0; 23 }

1022: [SHOI2008]小約翰的遊戲John9(Auti_SG)