A[]
给定一个大小为n<=100000
和的数组0<=A[i]<=2^64
,并且 的每两个相邻元素A[]
在其二进制表示中恰好有一个不同的数字。现在我们必须检查数组中是否存在任何4
元素,例如和。A[i1],A[i2],A[i3] and A[i4]
1<=i1<i2<i3<i4<=n
A[i1] xor A[i2] xor A[i3] xor A[i4] = 0
6 回答
提示: 在这些规则下,两个数字异或可以为零吗?为什么或者为什么不?这两个数字相互之间会是什么样子?
由于两个相邻的数字相差一个二进制位,因此将两个相邻的数字异或的结果非常可预测:
x
表示其值无关紧要的位,但与对应的x
下方/上方相同。
xxxxxxxxxxxxx1xxxxxxxxxxxx
xor: xxxxxxxxxxxxx0xxxxxxxxxxxx
__________________________________
00000000000001000000000000
对于您描述的集合中的任何两个相邻数字都是如此。
如果你能找到另一对相邻的数字,它们相差相同的位,它们也会异或到相同的值:00000000000001000000000000
最后,对这两个值进行异或运算肯定会给你一个零的最终答案。
所以你想要的算法看起来像:
- 识别数字与其后继位之间的不同位(位 0-63)
- 找到另一对也与步骤 1 中标识的相同位不同的数字。
这些是你的 4 个价值观。
请注意,如果 N > 64,那么根据鸽巢原理,必须有这样的解决方案。
如果N <= 64
,可能有这种形式的解,也可能有另一种形式的解,我这里就不描述了。
还有其他约束也可以找到 4 个异或 0 的数字。
但这可能是搜索解决方案的最简单方法。
但是,无法以这种方式找到解决方案并不能保证没有解决方案。
提示:查看异或的真值表:
A | B | Output
- + - + - - -
0 | 0 | 0
0 | 1 | 1
1 | 0 | 1
1 | 1 | 0
现在,什么二进制数与 10101 异或为 0?
这些是要查找的数字类型。
编辑:一旦你发现这些数字之间的关系是什么,你似乎从你对@abelenky 的回答的评论中得到了,你必须看看问题的其他部分。由于每个相邻元素在其二进制表示中都有一个不同的数字,这对于我们正在寻找的两个相邻元素的可能性意味着什么?
这是来自 CodeChef 目前正在进行的算法竞赛的一个问题。问题的链接是http://www.codechef.com/JULY12/problems/GRAYSC。所以这是不公平手段的使用,应该删除问题。
提示:如果您完全卡住,请尝试 O(n^4) 解决方案:
for i = 0 to N-3
for j = i+1 to N-2
for k = j+1 to N-1
for l = k+1 to N
if a[i] XOR a[j] XOR a[k] XOR a[l] is equal to 0 then
print a[i], a[j], a[k], a[l]
仔细观察两个相邻数字的异或的所有可能值,总共有多少不同的值是可能的?一旦你弄清楚了这一点,你就会得到答案。