John-博弈hdu

Problem Description
Little 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.

 

 

Input
The 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

 

 

Output
Output T lines each of them containing information about game winner. Print “John” if John will win the game or “Brother” in other case.

 

 

Sample Input
2
3
3 5 1
1
1
 

 

Sample Output
John
Brother
/*巴什博弈:
如果是一堆取棋子的问题,每个人轮流取棋子 ,Q棋子总数为n,最多可取m个,至少取1个,最后取完者胜,我们可以判断若n%(m+1)==0,
则先手负,因为只要后手保证每次拿的个数与对手拿的个数和为m+1,就一定能剩下棋子给自己。若n%(m+1)!=0,则先手胜。
相反若最后取完者败,n%(m+1)==0,则先手胜,先手先取若干个,以后对手每次取的时候都保证拿得个数与对手拿的个数和为m+1,
后面就可用剩一个让对方取
尼姆博弈:
以上就是道例题,有不同堆,胜负与游戏规则无关(即谁最后取剩,或最后取败),因为只要将个堆的个数求异或,若不为零则先手就
可以控制自己想要的局面(特例,每堆都是1,若取完则负则要考虑堆数是否为奇数)
解题:
郁闷,最近老是碰见WA,冤神~~~开始先把result赋为1,再与每个输入的数异或,后来想想只能二进制是各位数与1异或才等于本身
第二次WA就是flag的值每判断好,人家d还没值呢就开始判断d了*/
#include<stdio.h>
int main()
{
 register int i,j;
 int t,n,result,d,flag;
 
 scanf("%d",&t);
  for(i=0;i<t;i++)
  {
   flag=0;
   scanf("%d",&n);
   scanf("%d",&result);
   if(result>1) flag=1;
   for(j=1;j<n;j++)
   {
    scanf("%d",&d);
    if(d>1) flag=1;  
    result=result^d;
   }
  
   if(result!=0&&flag==1||flag==0&&n%2==0) printf("John/n");
   else printf("Brother/n");
  
  }
 
  return 0;
}
例2http://acm.pku.edu.cn/JudgeOnline/problem?id=1704

/*我们把棋子按位置升序排列后,从后往前把他们两两绑定成一对。如果总个数是奇数,就把最前面一个和边界(位置为0)绑定。

在同一对棋子中,如果对手移动前一个,你总能对后一个移动相同的步数,所以一对棋子的前一个和前一对棋子的后一个之间有多少个空位置对最终的结果是没有影响的。

于是我们只需要考虑同一对的两个棋子之间有多少空位。

这样一来,题目就转换成了就成了POJ 1067 取石子问题,直接对每一段空位置的长度求异或就可以了。*/

 

#include<stdio.h>
#include<stdlib.h>
int comp(const void *a,const void *b){
          return *(int *)a-*(int *)b;
}
int main()
{
 register int i;
 int a[1000];
 int t,n,ret;freopen("E://in.txt","r",stdin);
 scanf("%d",&t);
 while(t--)
 {
  scanf("%d",&n);
  if(n%2) {a[0]=0;i=1;n++;}
  else i=0;
  for(;i<n;i++)
   scanf("%d",&a[i]);
  qsort(a,n,sizeof(a[0]),comp);
  ret=a[1]-a[0]-1;
  for(i=2;i<n-1;i=i+2)
   ret=ret^(a[i+1]-a[i]-1);
  if(ret) printf("Georgia will win/n");
  else printf("Bob will win/n");
 }
 return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值