我一直试图弄清楚如何解决这个问题,有人可以给我一个算法或一系列步骤来解决这个问题吗?我真的很难过。代码不是必需的。我打算解决它的Python3,C和Rust。
考虑四个数字:a,b,c和k。您必须在a和b中最多改变k位以形成满足等式a'|的数字a'和b' b'= c。 |表示按位OR运算。
如果不存在此值,请返回-1。如果有多种解决方案,请尽可能小;如果仍有多个解决方案,请使b'尽可能小。
如果a中改变的比特数是k.a(类似于b的b.b),那么k.a + k.b <= k。
答案 0 :(得分:2)
我假设所需的结果是XOR-mask,即。带有1的数字,其中应该更改位,0应该保持不变(以便a XOR amask = a'
和b XOR bmask = b'
)
为了完整起见,a' | b'
的结果有1位,其中a&#39;或b&#39;或两者都有1,否则为0.
a' | b' = c
首先,绝对必要的条件是,&#39;也不是b&#39;有1位,其中c有0位。换句话说,要获得第一个amask和bmask,你可以取a和b并将每个位设置为0,其中c为1.换句话说,要获得第一个amask和bmask,你可以取a和b并设置每个位为0,其中c的二进制补码为0。
amask = a & (~c)
bmask = b & (~c)
现在计算amask和bmask中有多少位为1(带有一个朴素循环,或者使用多个popcount函数之一在线),并从你的k中减去它。如果k变为负数,则没有解(返回-1)。
第二部分要求你找到a和b都为0但c为1的位。简而言之:
temp_mask = c & ((a XOR amask) | (b XOR bmask))
temp_mask是你需要在 a或b中设置为1的位(哪一个取决于&#34;最小&#34;要求。但首先,pop-count temp_mask也是如此,如果结果比你剩下的k大,没有解决方案(返回-1)。
下一步很简单:
amask = amask | temp_mask
之前的amask有1,其中c为0,此语句现在不会重叠任何内容。
现在,您至少有一个a' | b' = c
的解决方案,即
(a XOR amask) | (b XOR bmask) = c
但是仍然可能有另一个更小的a,对吗?
这也不是很难:(a XOR amask)
中的1位,(b XOR bmask)
中的0位的每一位都可以&#34;移动&#34;,即。将其设为(a XOR amask)
中的0和(b XOR bmask)
中的1。结果c将是相同的,但(a XOR amask)
的数值将更小(可能,最差情况下它保持不变)。
temp_mask = (a XOR amask) & (~(b XOR bmask))
amask = amask XOR temp_mask
bmask = bmask XOR temp_mask
为了实现这一点,请注意unsigned
和int size。
完全伪代码:
amask = a & (~c)
bmask = b & (~c)
temp_mask = c & ((a XOR amask) | (b XOR bmask))
amask = amask | temp_mask
temp_mask = (a XOR amask) & (~(b XOR bmask))
amask = amask XOR temp_mask
bmask = bmask XOR temp_mask
答案 1 :(得分:1)
缓慢的方式:
使用此信息加快速度:
在a:a&amp;中找到额外的位。 ~c(无论如何都需要删除)
在b中找到额外的位:b&amp; ~c(无论如何都需要删除)
找到缺失的位:〜(a | b)&amp; c(需要在b'中设置以保持'小)
如果相应位计数的总和是&lt; = k。
,则可行