CodeJam Old Magician - 异或运算的应用

问题描述:

A magician does the following magic trick. He puts W white balls and B black balls in his hat and asks someone from the audience, say Bob, to remove pairs of balls in whatever order Bob would desire. After removing a pair of balls, Bob is asked to place a white ball back into the hat if they are the same color. Otherwise he is asked to place a black ball into the hat. 
When Bob is left with only one ball in the hat, he asks the magician what color the last ball is. Needless to say, the magician can't see the order by which Bob does the replacements. 

The problem is that the magician, like most magicians, is old and sometimes forgets how to do the trick. Being the kind person you are, you are going to help the magician. 

For each pair of numbers (W,B) you are asked to output one of the following: 

"WHITE" - if the last ball in the hat will be white for sure.
"BLACK" - if the last ball in the hat will be black for sure.
"UNKNOWN" - if you can't be sure of the last ball's color.


Input
The first line of the input file contains the number of cases, N. N test cases follow. 
Each case contains W and B on a line separated by a space. 


Output
For each input case, you should output: 
Case #X: Ywhere X is the number of the test case and Y is either "WHITE", "BLACK" or "UNKNOWN" as explained above. (quotes for clarity) 


Limits:0 < N ≤ 1000, W + B > 0 
Small dataset: 0 ≤ W ≤ 109, 0 ≤ B ≤ 109 

Large dataset: 0 ≤ W ≤ 1000, 0 ≤ B ≤ 1000

Sample:

Input 

2
3 1

3 6

Output 

BLACK

WHITE

问题分析:

这是一个比较老的题目了,同学提问的,竟然做了,就总结一下吧哈。题目的大概意思是,一个魔术师在一个帽子里面放一下白球和黑球,然后让一个人每次取两个球,如果两个球颜色一样,就放回一个白球,如果两个球颜色不一样,就放回一个黑色的球,问,最后剩下一个球时,是什么颜色的?,很显然,魔术师一定知道什么颜色,要不魔术师就没的玩了。一开始想到了是递归,很显然,当 W、B比较大的情况下是运算不出结果的。后来查阅了一些资料介绍用异或运算,感觉真是太神奇了。先复习一下异或运算的性质。

异或运算的性质:

1、交换律:a ⊕ b = b ⊕ a
2、结合律:(a ⊕ b) ⊕ c = a ⊕ (b ⊕ c)
3、对于任何数 x,都有 x ⊕ x=0,x ⊕ 0 = x
4、自反性: A B B = A  0 = A

所以可以得出,异或运算结果和运算顺序无关。现在再看题目,你会发现,其中的黑球和白球就相当于 10,并且是两个进行异或操作,由于异或操作跟顺序无关,所以直接进行异或运算就可以得出结果。继续分析的话会发现,异或操作只和1的个数有关,所以只要计算黑球的个数是偶数还是奇数个就可以得出结果。

例如:W=3,B=6,换成01表示,得出000111111,所有组合中的一个(因为不同的组合的异或运算结果是相等的),此时进行异或运算:0 ⊕ 0 ⊕ ⊕ ⊕ ⊕ ⊕ ⊕ ⊕ 1 = 0,很显然,1的个数为偶数时(6个1吗),结果为 0,即为白球,如果1个数为奇数,那么结果为1,即为黑球,到后来就是判断黑球个数是否为偶数了。

Python实现:

# @Time   :2018/6/26
# @Author :LiuYinxing
# 解题思路  运用异或运算的性质


class Solution:
    def oldMagician (self, W, B):
        if W <= 0 and B <= 0:
            return None
        if B % 2:
            return 'BLACK'
        else:
            return 'WHITE'


if __name__ == '__main__':
    solu = Solution()
    W, B = 1, 1
    print(solu.oldMagician(W, B))

异或运算的其他有趣的应用:

(1)两个数的交换

:下面是两个数交换不使用中间变量,(Python中有更简单的方法哦)

# @Time   :2018/6/26
# @Author :LiuYinxing
# 解题思路  运用异或运算的性质,进行两个数交换
# 异或运算是它本身的逆运算  (a ⊕ b) ⊕ b = a


def swap(a, b):
    a = a ^ b
    b = a ^ b
    a = a ^ b
    return a, b


if __name__ == '__main__':
    a, b = 5, 9
    a, b = swap(a, b)
    print(a, b)

(2)判断两个数是否相等

看一个例子,LeetCode:136. Single Number

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。

说明:你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?

示例 1:

输入: [2,2,1]
输出: 1

示例 2:

输入: [4,1,2,1,2]
输出: 4

Python3实现:

# @Time   :2018/6/26
# @Author :LiuYinxing
# 解题思路  运用异或运算的性质,对于任何数 x,都有 x ⊕ x=0,x ⊕ 0 = x


class Solution:
    def singleNumber(self, nums):
        """
        :type nums: List[int]
        :rtype: int
        """
        n = len(nums)
        if n == 0: return 0

        rst = 0
        for v in nums:
            rst ^= v

        return rst


if __name__ == '__main__':
    nums = [4, 1, 2, 1, 2]
    solu = Solution()
    print(solu.singleNumber(nums))
(3)二进制数位数的奇偶判断

例如:a = 000111111,将 a 中的每一位按位逐一进行异或,得,0 ⊕ 0 ⊕ 0 ⊕ 1 ⊕ 1 ⊕ 1 ⊕ 1 ⊕ 1 ⊕ 1 = 0,很便捷地就得出1的个数为偶数

猜你喜欢

转载自blog.csdn.net/xx_123_1_rj/article/details/80809998
old
今日推荐