zoukankan      html  css  js  c++  java
  • HDU3032 Nim or not Nim?(Lasker’s Nim游戏)

    Nim or not Nim?

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 3759    Accepted Submission(s): 1937


    Problem Description
    Nim is a two-player mathematic game of strategy in which players take turns removing objects from distinct heaps. On each turn, a player must remove at least one object, and may remove any number of objects provided they all come from the same heap.

    Nim is usually played as a misere game, in which the player to take the last object loses. Nim can also be played as a normal play game, which means that the person who makes the last move (i.e., who takes the last object) wins. This is called normal play because most games follow this convention, even though Nim usually does not.

    Alice and Bob is tired of playing Nim under the standard rule, so they make a difference by also allowing the player to separate one of the heaps into two smaller ones. That is, each turn the player may either remove any number of objects from a heap or separate a heap into two smaller ones, and the one who takes the last object wins.
     
    Input
    Input contains multiple test cases. The first line is an integer 1 ≤ T ≤ 100, the number of test cases. Each case begins with an integer N, indicating the number of the heaps, the next line contains N integers s[0], s[1], ...., s[N-1], representing heaps with s[0], s[1], ..., s[N-1] objects respectively.(1 ≤ N ≤ 10^6, 1 ≤ S[i] ≤ 2^31 - 1)
     
    Output
    For each test case, output a line which contains either "Alice" or "Bob", which is the winner of this game. Alice will play first. You may asume they never make mistakes.
     
    Sample Input
    2 3 2 2 3 2 3 3
     
    Sample Output
    Alice Bob
     
    Source
     
    Recommend
    gaojie   |   We have carefully selected several similar problems for you:  3031 3033 3038 3035 3034 
     
    题解:

    每一轮允许两会中操作之一:①从一堆石子中取走任意多个②将一堆数量不少于2的石子分成都不为空的两堆。
    这个问题可以用SG函数来解决。首先,操作①其实和Nim游戏没什么区别,对于一个石子数为k的点来说,后继可以为0…k-1。而操作②实际上是把一个游戏分成了两个游戏。根据游戏的和的概念,这两个游戏的和应该为两个子游戏的SG函数值的异或。而求某一个点的SG函数要利用它的后继,它的后继就应该为当前局面能产生的所有单一游戏,以及当前局面所有能分成的多个单一游戏的游戏的和。
    比如说,状态3的后继有:0、1、2、(1,2),他们的SG值分别为0、1、2、3,所以sg(3) = 4。
    那么这样,我们就能用SG函数解决这个问题。
    但是,如果数据范围非常大的时候SG函数就不能用了,通过打表可以发现一个更优美的结论:

    if(x%4==0) sg[x]=x-1;
    if(x%4==1||x%4==2) sg[x]=x;
    if(x%4==3) sg[x] = x+1。

     
    参考代码:
    #include<bits/stdc++.h>
    using namespace std;
    #define N 1000000
    int T,n,x,ans;
    
    int get_sg(int x)
    {
        if(x%4==0) return x-1;
        else if(x%4==1||x%4==2) return x;
        else if(x%4==3) return x+1;
    }
    int main()
    {
        scanf("%d",&T);
        while (T--)
        {
            scanf("%d",&n);ans=0;
            for(int i=1;i<=n;++i)
            {
                scanf("%d",&x);
                ans^=get_sg(x);
            }
            if(ans) puts("Alice");
            else puts("Bob");
        }
        return 0;
    }
    View Code
  • 相关阅读:
    div水平居中和垂直居中
    HTML流动布局各种宽度自适应
    PHP导出大量数据到excel表格
    等比例压缩图片到指定的KB大小
    SQLServer数据库中创建临时表
    Mysql数据库表关于几个int类型的字符长度
    JS 获取浏览器和屏幕宽高信息
    CTSC2018 & APIO2018 颓废 + 打铁记
    [UOJ#192]【UR #14】最强跳蚤
    ZJOI2018 Day2 滚粗记 + 流水账
  • 原文地址:https://www.cnblogs.com/csushl/p/11584375.html
Copyright © 2011-2022 走看看