我正在编写采用A 1<A<2*50
的代码,找到一个值A+B==A^B
我尝试过,但是对于巨大的价值,解决方案用尽了内存
def solve(A):
if A==1:
return 2
for i in xrange(1,A+1):
if A+i==A^i:
return i
预期会获得更大的价值
答案 0 :(得分:4)
您需要查看XOR的属性。从用于XOR的真值表开始,该表应用于单个位:
A | B | A ^ B
----|-----|--------
0 | 0 | 0
0 | 1 | 1
1 | 0 | 1
1 | 1 | 0
将此与A + B
A | B | A + B
----|-----|--------
0 | 0 | 0
0 | 1 | 1
1 | 0 | 1
1 | 1 | 10 # requires two bits!
因此,对于A
的任何给定位值,B
中对应位有2个可能的罗格值1,它们将导致完全相同的结果使用A ^ B
或A + B
。因此,对于A
的任何值,B
至少有1个值,其中A + B == A ^ B
。如果A中的位设置为零(并且B可以超过2 ** 50,则此类位的数量是无限的),那么B会有更多选择。
如果您只需要生成一个数字 ,那么最简单的事情就是让您专注于这些表中的A = 0, B = 1
和A = 1, B = 0
选项。因为如果您将A
的值与 only 1进行XOR运算,则您会将A
的所有位都变成了完全相反的值,因此创建了为每个B = 1
设置A = 0
,为每个B = 0
设置A = 1
。
例如,取数字42,它以二进制形式表示为101010
(1 x 32、0 x 16、1 x 8、0 x 4、1 x 2和0 x 1,总和为42)。将其与二进制数11111
(十进制为63)进行异或,然后翻转所有位:
>>> format(42, '06b') # 42 in binary, the 6 lower bits
'101010'
>>> 0b111111 # binary number with 6 bits, all 1
63
>>> format(42 ^ 0b111111, '06b') # XOR with 63, still 6 bits
'010101'
>>> 42 ^ 0b111111 # now in decimal
21
那是您最好的B
候选人,将它们加在一起并在这些元素上使用XOR即可得到一个设置了全部6位的数字,因此又是63:
>>> 42 + 21
63
>>> 42 ^ 21
63
您如何知道要使用多少次叮咬?使用int.bit_length()
method:
>>> (42).bit_length()
6
如何制作一个使用任意数量的位(都设置为1)的整数?通过将2的幂乘以位长,然后减去1:
>>> 2 ** 6
64
>>> 2 ** 6 - 1
63
>>> format(2 ** 6 - 1, 'b')
'111111'
因此解决方案是:
def solve(a):
return a ^ 2 ** a.bit_length() - 1
这也轻松解决了2 ** 50的问题:
>>> A = 42
>>> B = solve(A)
>>> A + B == A ^ B
True
>>> A = 2 ** 50
>>> B = solve(A)
>>> A + B == A ^ B
True
如果要查看A的所有位置为0的所有位置,则可以为B
生成一个 lot 个更多的值。只需从a ^ 2 ** 50 - 1
开始,然后获取现在设置为1
的每个位(在A中设置为0
),并产生将它们设置为0
的所有可能组合再次。这些组合中的每一个都是B
的另一个有效值。我不会为此生成代码,因为对于A = 2
,它包括4到2 ** 50之间的所有整数,因此,除了B
之外,还有1.125.899.906.842.621不同的可能值。 B = 1
。
答案 1 :(得分:0)
让B = A的按位补码。
A + B = 111111111
A xor B = 11111111
答案 2 :(得分:0)
假设给定正整数A,我们想找到满足以下条件的最小正整数B:A + B = A ^ B(A XOR B)
1)对于所有偶数A(2,4,6,8 ...),B = 1 [原因:对于所有偶数,LSB均为0,所以加1将满足我们的条件]
2)对于奇数A,B的幂为2。从2开始检查
------代码段(未测试)------------
def FindB(A):
if A%2 == 0:
return 1
else:
while True:
B = 2
if A+B == A^B:
return B
B *= 2