zoukankan      html  css  js  c++  java
  • 由黑球白球问题相到的

    一个袋子里有100个黑球和100个白球,每次从袋子里面取出两个球扔掉,

    规则如下:如果取出的两个球颜色相同则放入袋中一个黑球,不同则放入一个白球。

    例如:从袋子中取出一白一黑两个球,那么则将这两个球扔掉,然后重新放回袋子中一个白球。如果取出两个白球,则放回一个黑球。

    问题:最后剩余的一个球的颜色是黑色还是白色?

    出自《编程之美》

    思路:

    1.问题抽象:

    相同为黑,不同为白,您能想到某种计算机位操作吗?

    异或,好吧,我没有想到。设白球为1,黑球为0,那么取球的规则就被简化为对100个0和100个1做无序的异或操作。

    假如您只知道异或操作的性质想必您一定知道了答案。

    不知道也没有关系

    2.问题归纳简化

    1)假设袋子中只有一白一黑两个球:那么1^0=1 , 即剩下一个白球

    2)假设有两个白球两个黑球:1^0^1^0=0 , 0^0^1^1=0, ...,发现怎样组合都可以,你是不是想起异或操作是否满足交换律与结合率,赶紧在纸上画画,发现果然如此。

    ...

    如果操作满足结合率和交换律,那么说明这些100个0和100个1做异或操作的顺序无论如何变都一样。

    下面有两种思路,

    逆向:既然可以随意组合,那么组合成这样:(0^0^...^0)[100]^(1^1^...^1)[100],很容易看出,前面括号里的一大堆0做异或操作都是0。后面的一堆1可能比较棘手。好吧,继续归纳简化:

    1^1=0,

    1^1^1=1,

    1^1^1^1=0

    ...难道与奇偶有关系?奇数个1做异或都为1,偶数个则为0,能用归纳法给出证明吗?很简单,不说了

    我们的问题从(0^0^...^0)[100]^(1^1^...^1)[100] 简化为 0^0=0.

    好吧,给出结论:无论您手多高多牛,最后剩下的一定是“0”代表的黑球。

    异或的还有一个用途:不用中间值的交换a和b的算法

    void swap(int& a , int& b)

    {

        a=a^b;

        b=a^b;

        a=a^b;

    }

    它利用了异或操作的一个性质:

    a^b^b=a

    a^b^a=b

  • 相关阅读:
    codechef Taxi Driver
    BZOJ2190 SDOI2008 仪仗队
    BZOJ 1070: [SCOI2007]修车
    BZOJ 1066 [SCOI2007]蜥蜴
    最大流模板
    表达式计算
    codechef Polo the Penguin and the Tree
    LCA 求 树中两个点的距离
    Baby Step Giant Step model
    POJ 1330 Nearest Common Ancestors (LCA,dfs+ST在线算法)
  • 原文地址:https://www.cnblogs.com/cherri/p/1999680.html
Copyright © 2011-2022 走看看