zoukankan      html  css  js  c++  java
  • HDU 1907 John nim博弈变形

    John



    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
     
    题意:
      今有若干堆火柴,两人依次从中拿取,规定每次只能从一堆中取若干根, 可将一堆全取走,但不可不取,最后取完者为负。
    题解:
      T态:异或和为0+
      S态:异或和不为0+
      定义:若一堆中仅有1根火柴,则被称为孤单堆。若大于1根,则称为充裕堆。
      定义:T态中,若充裕堆的堆数大于等于2,则称为完全利他态,用T2表示;若充裕堆的堆数等于0,则称为部分利他态,用T0表示。
     
    孤单堆的根数异或只会影响二进制的最后一位,但充裕堆会影响高位(非最后一位)。一个充裕堆,高位必有一位不为0,则所有根数异或不为0。故不会是T态。
    [定理5]:S0态,即仅有奇数个孤单堆,必败。T0态必胜。 
    证明:
    S0态,其实就是每次只能取一根。每次第奇数根都由己取,第偶数根都由对 
    方取,所以最后一根必己取。败。同理,  T0态必胜#
    [定理6]:S1态,只要方法正确,必胜。 
    证明:
    若此时孤单堆堆数为奇数,把充裕堆取完;否则,取成一根。这样,就变成奇数个孤单堆,由对方取。由定理5,对方必输。己必胜。  # 
    [定理7]:S2态不可转一次变为T0态。 
    证明:
    充裕堆数不可能一次由2变为0。得证。  # 

    [定理8]:S2态可一次转变为T2态。 
    证明:
    由定理1,S态可转变为T态,态可一次转变为T态,又由定理6,S2态不可转一次变为T0态,所以转变的T态为T2态。  # 
    [定理9]:T2态,只能转变为S2态或S1态。 
    证明:
    由定理2,T态必然变为S态。由于充裕堆数不可能一次由2变为0,所以此时的S态不可能为S0态。命题得证。 
    [定理10]:S2态,只要方法正确,必胜. 
    证明:
    方法如下: 
          1)  S2态,就把它变为T2态。(由定理8) 
          2)  对方只能T2转变成S2态或S1态(定理9)
        若转变为S2,  转向1) 
        若转变为S1,  这己必胜。(定理5) 
    [定理11]:T2态必输。 
    证明:同10。 
    综上所述,必输态有:  T2,S0 
              必胜态:    S2,S1,T0. 

    #include <iostream>
    #include <cstdio>
    #include <cmath>
    #include <cstring>
    #include <algorithm>
    using namespace std;
    #pragma comment(linker, "/STACK:102400000,102400000")
    #define ls i<<1
    #define rs ls | 1
    #define mid ((ll+rr)>>1)
    #define pii pair<int,int>
    #define MP make_pair
    typedef long long LL;
    const long long INF = 1e18+1LL;
    const double Pi = acos(-1.0);
    const int N = 5e5+10, M = 2e5+20, mod = 1e9+7, inf = 2e9;
    
    int sg[N],n,x,ans,vis[N];
    int main() {
        int T;
        scanf("%d",&T);
        while(T--) {
            scanf("%d",&n);
            int ans = 0, cnt = 0;
            for(int i = 1; i <= n; ++i) {
                scanf("%d",&x);
                ans = ans ^ x;
                if(x > 1) cnt++;
            }
            if((ans && cnt >= 2) || (cnt == 1) || (cnt == 0 && !ans)) puts("John");
            else puts("Brother");
        }
        return 0;
    }
  • 相关阅读:
    最优Django环境配置
    关于django migrations的使用
    js判断移动端是否安装某款app的多种方法
    Django升级1.9.6出现的中文本地化bug
    bootstrap响应式设计简单实践。
    Django单元测试简明实践
    Vue列表渲染
    vue 使用lib-flexable,px2rem 进行移动端适配 但是引入的第三方UI组件 vux 的样式缩小,解决方案
    Vue事件处理
    Vue表单输入绑定
  • 原文地址:https://www.cnblogs.com/zxhl/p/6010916.html
Copyright © 2011-2022 走看看