人人网笔试题1

来源:互联网 发布:淘宝关注店铺在哪里 编辑:程序博客网 时间:2024/05/12 00:50
七夕那天,雯雯的男朋友小俞给她买了一颗神奇的魔石。这颗魔石平常是暗淡无光的,但只要给这颗魔石擦上魔粉,魔石就会从内部发出不同颜色的绚丽光泽。非常好看。发出的光的颜色,是在魔石上擦的所有魔粉的编号的异或(Xor)值(如果异或值为0,也是一种颜色,异或值相同表示颜色相同)。雯雯手上现在一共有6种魔粉,编号是6 7 17 46 47 56。雯雯非常想知道这颗魔石究竟能发出多少种颜色的光。由于组合实在太多,雯雯便跑过来求助聪明的你,相信你不会让她失望。

如果魔粉有20种(编号256以内),又该如何计算?

转自@研究者July 的Blog 第35题
http://blog.csdn.net/v_july_v/article/details/7974418

二进制运算的特点:
① n个数做and操作,如果一个数出现多次,那么和它出现1次结果一致。
② n个数做or操作,如果一个数出现多次,那么和它出现1次结果一致。
③ n个数做xor操作,如果一个数出现奇数次,那么和它出现1次结果一致,偶数次和它没出现一致。

然后用归纳法:
假设我们有k种魔粉可以弄出s种颜色,那么加入第k+1种,会是什么情况?
1> 如果s已经包含了第k+1种,那么还是s种,因为我们可以用前k种通过xor运算替代第k+1种,然后再与前k种颜色做各种操作,根据二进制操作特点③,实际前k种颜色每种都不超过1,所以能形成的颜色种类并没有增长。
2> 如果s不包含第k+1种,那么结果一定是2s种,这是因为根据二进制操作特点③,新的颜色必然包含1个第k+1种颜色,否则它没出现的话,不可能形成新的颜色。而第k种颜色和之前的s种颜色进行xor,能得到新的s种颜色,新的s种颜色两两不等(否则除去第k+1种,原来的s种颜色存在重复),另外新的s种和老的s种不存在相同颜色(否则之前的s种颜色可以形成第k+1种颜色),所以结果一定是2s种。

f(x)表示使用x种魔粉能形成的颜色。
则f(0) = 1
f( n+1 ) = f(n) 或者 2*f( n ),必然是2的幂。

然后颜色的无关性可以通过将所有的颜色的2进制进行一个矩阵排列,找出这个矩阵的秩。

例如给定颜色1,3,7,那么矩阵就是

001
011
111

矩阵的秩是3,那么颜色总数就是2^3 = 8


第1问:就用2进制的枚举,也是很快的,总共6种魔粉,不能不选,全枚举的话是2^6 - 1。方法就是for(int i = 1; i <= 2^6; i++),然后将i转为长度为6的二进制,0对应不选,1对应选。最后将选中的异或就可以了。
 
第2问:用类似01整数背包的方法就可以求解,因为编号在256之内,因此能产生的颜色也不超过256种,那么用个长为256的bool数组,用来记录可以产生哪些编号的颜色。初始全为false。每加入一种魔粉,先用这种魔粉同已经存在的(值为true)的状态做Xor,并将结果对应的bool变量设为true。最后再将魔粉本身的编号设为true。这样总的复杂度为256*n,n为魔粉的数量。


zz from http://www.51nod.com/question/index.html#!questionId=671
原创粉丝点击