用于满足方程的按位变换算法

时间:2016-07-31 00:36:58

标签: algorithm bit-manipulation

我一直试图弄清楚如何解决这个问题,有人可以给我一个算法或一系列步骤来解决这个问题吗?我真的很难过。代码不是必需的。我打算解决它的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。

2 个答案:

答案 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或b中设置了一个位但未在c中设置,则将其复位为'和b'(计数:1或2)。
  • 如果在c中设置但是缺少a和b,则将其设置为b'(计数:1)。

使用此信息加快速度:

  • 在a:a&amp;中找到额外的位。 ~c(无论如何都需要删除)

  • 在b中找到额外的位:b&amp; ~c(无论如何都需要删除)

  • 找到缺失的位:〜(a | b)&amp; c(需要在b'中设置以保持'小)

如果相应位计数的总和是&lt; = k。

,则可行