Be the Winner
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 1233 Accepted Submission(s): 632
For example "@@@" can be turned into "@@" or "@" or "@ @"(two piles). two people get apples one after another and the one who takes the last is
the loser. Fra wants to know in which situations he can win by playing strategies (that is, no matter what action the rival takes, fra will win).
2 2 2 1 3
No YesJohn
Time Limit: 5000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Total Submission(s): 1674 Accepted Submission(s): 907
Problem DescriptionLittle John is playing very funny game with his younger brother. There is one big box filled with M&Ms of different colors. At first John has to eat several M&Ms of the same color. Then his opponent has to make a turn. And so on. Please note that each player has to eat at least one M&M during his turn. If John (or his brother) will eat the last M&M from the box he will be considered as a looser and he will have to buy a new candy box. Both of players are using optimal game strategy. John starts first always. You will be given information about M&Ms and your task is to determine a winner of such a beautiful game.
InputThe first line of input will contain a single integer T – the number of test cases. Next T pairs of lines will describe tests in a following format. The first line of each test will contain an integer N – the amount of different M&M colors in a box. Next line will contain N integers Ai, separated by spaces – amount of M&Ms of i-th color. Constraints: 1 <= T <= 474, 1 <= N <= 47, 1 <= Ai <= 4747
OutputOutput T lines each of them containing information about game winner. Print “John” if John will win the game or “Brother” in other case.
Sample Input2 3 3 5 1 1 1
Sample OutputJohn Brother
博弈模型:今有若干堆石子,两人依次从中拿取,规定每次只能从一堆中取若干个,
可将一堆全取走,但不可不取,最后取完者为负。
两题算法相同:详细点击 博弈总结
以下为精简版:
【定义1】:若一堆中仅有一个石子,则被称为孤单堆。若大于1个,则称为充裕堆。
【定义2】:T态中,若充裕堆的堆数大于等于2,则称为完全利他态,用T2表示;若充裕堆的堆数等于0,则称为部分利他态。用T0表示。
孤单堆的根数异或智慧影响二进制的最后以为,但充裕堆会影响高位(非最后一位)。一个充裕堆,高位必有一位不为0,则所有根数异或不为0。故不会是T态。
【定理1】:S0态,即仅有奇数个孤单堆,必败。T0态必胜。
证明:S0态,其实就是每次只能取一根。每次第奇数根都由自己取,第偶数根都由对方取,所以最后一根必由自己取。所以必败。同理:T0态必胜。
【定理2】:S1态,只要方法正确,必胜。
证明:若此时孤单堆堆数为奇数,把充裕堆取完;否则,取成一根。这样,就变成奇数个孤单堆,由对方取。由定理1,对方必输,己必胜。
【定理3】:S2态不可转一次变为T0态。
证明:充裕堆数不可能一次由2变为0。
【定理4】:S2态可一次转变为T2态。
证明:因为对于任何一个S态,总能从一堆中取出若干个使之成为T态。又因为S1态,只要方法正确,必胜。S2态不可转一次变为T0态,所以转变的T态为T2态。
【定理5】:T2态,只能转变为S2态或S1态。
证明:因为T态,取任何一堆的若干根都将成为S态。由于充裕堆不可能一次由2变为0,所以此时的S态不可能为S0态。得证。
【定理6】:S2态,只要方法正确,必胜。
证明:方法如下:
- S2态,就把它变为T2态。(定理4);
对方只能T2转变为S2态或S1态(定理5)。若转变为S2,则转向①。
若转变为S1,这时己必胜(定理1)。
【定理7】:T2态必输。
证明:同定理6.
综上所述:必输态有:T2、S0;必胜态有:S2、S1、T0。
2509AC代码:给出结论:先手胜当且仅当 ①所有堆石子数都为1且游戏的SG值为0(即有偶数个孤单堆-每堆只有1个石子数);②存在某堆石子数大于1且游戏的SG值不为0.
证明:
- 若所有堆都为1且SG值为0,则共有偶数堆石子,故先手胜。
i)只有一堆石子数大于1时,我们总可以对该石子操作,使操作后堆数为奇数且所有堆的石子数均为1;ii)有超过一堆的石子数1时,先手将SG值变为0即可,且总还存在某堆石子数大于1
因为先手胜。
#include <iostream> using namespace std; int main() { int n,a; while(cin>>n) { int flag=0; //用来标志是否存在充裕堆 int sum=0; //SG值 while(n--) {cin>>a; if(a>1) flag=1; sum^=a; } if((!flag&&sum==0)||(sum!=0&&flag)) //若不存在充裕堆且所有堆石子个数异或结果为0, //或存在充裕堆且所有堆石子个数异或结果不为0 cout<<"Yes"<<endl; else cout<<"No"<<endl; } return 0; }
1907AC代码:#include <iostream> using namespace std; int main() { int t,a,n; cin>>t; while(t--) { int flag; int sum=0; cin>>n; while(n--) {cin>>a; if(a>1) flag=1; sum^=a; } if((!flag&&sum==0)||(sum!=0&&flag)) cout<<"John"<<endl; else cout<<"Brother"<<endl; } return 0; }