回过头看HDU 5011 Game(2014西安区域赛)

Here is a game for two players. The rule of the game is described below:

● In the beginning of the game, there are a lot of piles of beads.

● Players take turns to play. Each turn, player choose a pile i and remove some (at least one) beads from it. Then he could do nothing or split pile i into two piles with a beads and b beads.(a,b > 0 and a + b equals to the number of beads of pile i after removing)

● If after a player’s turn, there is no beads left, the player is the winner.

Suppose that the two players are all very clever and they will use optimal game strategies. Your job is to tell whether the player who plays first can win the game.
Input
There are multiple test cases. Please process till EOF.

For each test case, the first line contains a postive integer n(n < 10 5) means there are n piles of beads. The next line contains n postive integer, the i-th postive integer a i(a i < 2 31) means there are a i beads in the i-th pile.
Output
For each test case, if the first player can win the game, ouput “Win” and if he can’t, ouput “Lose”

Sample Input
1
1
2
1 1
3
1 2 3

Sample Output
Win
Lose
Lose

这水题出在一堆那么难的题里真是迷……

题目大意是几堆珠子,每次一名玩家挑选任意一堆,取走任意数目,然后可以把这一堆里剩下的珠子随意分成两堆或不分。

一开始我在网上查的时候看到一种游戏叫“Take or break game”,就是这题里提到的游戏(拿取x,然后再拿合理的任意值(可为0)组成新的一堆),有一篇博客的里提到了这个名词,并表示应该需要用SG函数来解。

然而事实上,这题的代码可短了,跟poj 2234几乎一模一样,而2234这题就是最经典的nim游戏,n堆,选一堆随便拿。也就是说,增加的“分成两堆”动作对游戏局面产生的影响是0。

代码…..贴不贴呢,贴吧:

public class Main {
    public static void main(String[] args) {
        Scanner reader = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        while (reader.hasNext()) {
            int n = reader.nextInt();
            long ans = 0;
            for (int i = 1; i <= n; i++) {
                ans ^= reader.nextInt();
            }
            if (ans == 0) {
                out.println("Lose");
            } else {
                out.println("Win");
            }
        }
        out.close();
    }
}

poj 2234那题我的代码跑了89ms,这题跑了889ms….可见数据量还是蛮大的。
普普通通的连续异或操作,什么处理都没干。

我在一个知乎回答里,提到经典nim的异或操作源自对游戏局面“平衡”与否的判定,按照这个理论来解释为什么分成两堆的操作对胜败毫无影响,那就必然是因为,分成两堆的操作无论如何都不会改变局面的平衡性….

好的…..灵魂画手登场
超简易nim局面
嗯,这是一个超简易的平衡经典nim局面。至于为什么是平衡,什么是平衡,请用上面那个回答稍稍参考一下…..那么我们做个试验,把第一堆取走一个,然后分成两堆试试。首先取走一个:

取走一个

第一位只有一个方块儿,奇数,是的,他从平衡局面变成了不平衡。然后我们再分成两堆看看:

分成两堆

第一位,三个,奇数,是的依旧不平衡!!!这只是一个简单例子,我自己无法举出任何反例,我认为这个结论是成立的(因为这样做a了,所以这个结论是对的hhh,这就叫acm证明法)。

好的,这题的难度就到此为止了,什么take or break,去他的SG函数,连续异或大法好。这题就如此轻易的水过了。

博弈论这个坑有点大…..还有什么环形局面balabala一大堆我没去研究,这样下去不是个头,先跳坑了,去打打搜索题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值