1022: [SHOI2008]小约翰的游戏John【Nim博弈,新生必做的水题】
1022: [SHOI2008]小約翰的游戲John
Time Limit:?1 Sec??Memory Limit:?162 MBSubmit:?2709??Solved:?1726
[Submit][Status][Discuss]
Description
小約翰經(jīng)常和他的哥哥玩一個(gè)非常有趣的游戲:桌子上有n堆石子,小約翰和他的哥哥輪流取石子,每個(gè)人取
的時(shí)候,可以隨意選擇一堆石子,在這堆石子中取走任意多的石子,但不能一粒石子也不取,我們規(guī)定取到最后一
粒石子的人算輸。小約翰相當(dāng)固執(zhí),他堅(jiān)持認(rèn)為先取的人有很大的優(yōu)勢(shì),所以他總是先取石子,而他的哥哥就聰明
多了,他從來沒有在游戲中犯過錯(cuò)誤。小約翰一怒之前請(qǐng)你來做他的參謀。自然,你應(yīng)該先寫一個(gè)程序,預(yù)測(cè)一下
誰將獲得游戲的勝利。
Input
本題的輸入由多組數(shù)據(jù)組成第一行包括一個(gè)整數(shù)T,表示輸入總共有T組數(shù)據(jù)(T≤500)。每組數(shù)據(jù)的第一行包
括一個(gè)整數(shù)N(N≤50),表示共有N堆石子,接下來有N個(gè)不超過5000的整數(shù),分別表示每堆石子的數(shù)目。
Output
每組數(shù)據(jù)的輸出占一行,每行輸出一個(gè)單詞。如果約翰能贏得比賽,則輸出“John”,否則輸出“Brother”
,請(qǐng)注意單詞的大小寫。
Sample Input
23
3 5 1
1
1
Sample Output
JohnBrother
HINT
Source
Seerc2007
題目鏈接:http://www.lydsy.com/JudgeOnline/problem.php?id=1022
分析:
題目大意:反Nim游戲,即取走最后一個(gè)的人輸
首先狀態(tài)1:如果所有的堆都是1,那么堆數(shù)為偶先手必勝,否則先手必?cái)?/p>
然后狀態(tài)2:如果有兩個(gè)堆數(shù)量相同且不為1,那么后手擁有控場(chǎng)能力,即:
若先手拿走一堆,那么后手可以選擇將另一堆留下1個(gè)或者全拿走,使這兩堆最終只剩1個(gè)或0個(gè);
若先手將一堆拿剩一個(gè),那么后手可以選擇將另一堆留下一個(gè)讓先手拿或全拿走,使這兩堆最終只剩1個(gè)或0個(gè);
若先手將一堆拿走一部分,那么后手可以將另一堆同樣拿走一部分,然后同上
狀態(tài)3:若Xor!=0 那么先手可以先拿走一部分讓Xor=0 然后同狀態(tài)2先手必勝 否則先手必?cái)?/p>
于是若所有堆全是1 Xor==0先手必勝 否則后手必勝
若有堆不是1 Xor==0后手必勝 否則先手必勝
下面給出AC代碼:
1 #include <stdio.h> 2 int T,n,x; 3 int main() 4 { 5 while(scanf("%d",&T)!=EOF) 6 { 7 while(T--) 8 { 9 int flag=0,sum=0; 10 scanf("%d",&n); 11 for(int i=1;i<=n;i++) 12 { 13 scanf("%d",&x); 14 sum^=x; 15 if(x!=1) 16 flag=1; 17 } 18 if((sum==0&&flag==0)||(sum!=0&&flag==1)) 19 printf("John\n"); 20 else 21 printf("Brother\n"); 22 } 23 } 24 return 0; 25 }?
轉(zhuǎn)載于:https://www.cnblogs.com/ECJTUACM-873284962/p/6956279.html
總結(jié)
以上是生活随笔為你收集整理的1022: [SHOI2008]小约翰的游戏John【Nim博弈,新生必做的水题】的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎样让你的安卓手机瞬间变Firefox
- 下一篇: C# LINQ系列:LINQ to Da