zoukankan      html  css  js  c++  java
  • POJ1704题解——阶梯博弈入门

    题目链接:http://poj.org/problem?id=1704

    Georgia and Bob

    Georgia and Bob decide to play a self-invented game. They draw a row of grids on paper, number the grids from left to right by 1, 2, 3, ..., and place N chessmen on different grids, as shown in the following figure for example: 

    Georgia and Bob move the chessmen in turn. Every time a player will choose a chessman, and move it to the left without going over any other chessmen or across the left edge. The player can freely choose number of steps the chessman moves, with the constraint that the chessman must be moved at least ONE step and one grid can at most contains ONE single chessman. The player who cannot make a move loses the game.

    Georgia always plays first since "Lady first". Suppose that Georgia and Bob both do their best in the game, i.e., if one of them knows a way to win the game, he or she will be able to carry it out. 

    Given the initial positions of the n chessmen, can you predict who will finally win the game? 

    Input

    The first line of the input contains a single integer T (1 <= T <= 20), the number of test cases. Then T cases follow. Each test case contains two lines. The first line consists of one integer N (1 <= N <= 1000), indicating the number of chessmen. The second line contains N different integers P1, P2 ... Pn (1 <= Pi <= 10000), which are the initial positions of the n chessmen.

    Output

    For each test case, prints a single line, "Georgia will win", if Georgia will win the game; "Bob will win", if Bob will win the game; otherwise 'Not sure'.

    Sample Input

    2
    3
    1 2 3
    8
    1 5 6 7 9 12 14 17
    

    Sample Output

    Bob will win
    Georgia will win

    题目意思:

    题目的意思是说:两个人在一个1*N的格子内挪动棋子,刚开始在若干个位置上有若干个棋子,每一个选手可以进行的操作时选择一个棋子并把它向左方移动,不能越过其它的棋子,也不能超出边界。谁不能移动谁就输了。求谁会赢?

    分析:

    我们把棋子按位置升序排列(因为有可能他给你的就是没有顺序的)后,从后往前把他们两两绑定成一对。如果棋子总个数是奇数,就把最前面一个和边界(位置为0)绑定。 在同一对棋子中,如果对手移动前一个,你总能对后一个移动相同的步数,所以一对棋子的前一个和前一对棋子的后一个之间有多少个空位置对最终的结果是没有影响的。于是我们只需要考虑同一对的两个棋子之间有多少空位。我们把每一对两颗棋子的距离(空位数)视作一堆石子,在对手移动每对两颗棋子中靠右的那一颗时,移动几位就相当于取几个石子,与取石子游戏对应上了,各堆的石子取尽,就相当再也不能移动棋子了。
    我们可能还会考虑一种情况,就是某个玩家故意破坏,使得问题无法转换为取石子,例如前一个人将某对中的前者左移,而当前玩家不将这对中的另一移动,则会导致本堆石子增多了,不符合nim。但是这种情况是不会出现的。因为赢家只要按照取石子进行即可获胜(他要是聪明或者说想赢就绝对不会这么干),而输家无法主动脱离取石子状态。如果输家想要让某堆石子增多,那么赢家只需要让该堆减少回原状,这样输家又要面临跟上一回合同样的局面。

    #include <iostream>
    #include <stdio.h>
    #include <algorithm>
    #define  maxn 1010
    using namespace std;
    int main()
    {
        int t,a[maxn];
        scanf("%d",&t);
        while(t--)
        {
            int n,sum=0;
            scanf("%d",&n);
            for(int i=1; i<=n; i++)
            {
                scanf("%d",&a[i]);
            }
            a[0]=0;
            sort(a+1,a+n+1);
            for(int i=n; i>0; i=i-2)
            {
                sum^=(a[i]-a[i-1]-1);
            }
            if(sum)printf("Georgia will win
    ");
            else printf("Bob will win
    ");
        }
        return 0;
    }
    View Code

    下面说一下阶梯博弈,连解释带图都借鉴(chaoxi)过来了:

    定义
    即有n个阶梯呈升序排列,每个阶梯上有若干个石子,可行的操作是将一个阶梯上的石子移任意个(>0)到前一个台阶。当没有可行操作时(所有石子都被移动到了地面,即第0号台阶)输。

    转化
    阶梯博弈实际上还是Nim游戏(所以Nim真的很重要),它等价于奇数号台阶的Nim游戏。

    证明
    为什么是奇数号台阶呢?
    因为除了1号台阶之外,每种操作都是可以对应的。

    倘若你的对手移动的是奇数号台阶,那么按照Nim游戏的移法进行移动即可。
    倘若你的对手移动的是偶数号台阶(2n),那么我们就把等量的石子从2n-1移动到2n-2,对奇数号台阶没有任何影响。

    这么移动的话,最后奇数号台阶上就不会有石子了。然后就会开始移动偶数号台阶2n。同样的把等量的石子从2n-1移动到2n-2。因为台阶编号始终≥2,因此最后一步必然是我们的。

    如果换成偶数的话,当后手移动1号台阶时,我们就无法对其进行模仿了。因此只有奇数号是可行的。

    结论
    如果奇数号台阶上石子数的异或和=0,则先手必败。
    ————————————————

    以上论述转自:(稍有改动)
    版权声明:本文为CSDN博主「forezxl」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
    原文链接:https://blog.csdn.net/a1799342217/article/details/78265265

  • 相关阅读:
    字母运算
    7.5 字典序全排列
    5
    4 c#
    c# 贪吃蛇源码
    【Django】django.core.exceptions.ImproperlyConfigured: mysqlclient 1.4.0 or newer is required;
    redis 存储验证码 基本使用
    Git 的基本使用
    docker(专业版) 安装过程报错
    router.push query 路由 跳转 传参使用
  • 原文地址:https://www.cnblogs.com/Mingusu/p/11704042.html
Copyright © 2011-2022 走看看