如何找到差异为给定常数且按位与为零的对的数量?基本上,所有(x,y)使得 x-y = k;其中k是给定的常数, x&y = 0;
答案 0 :(得分:1)
一个有趣的问题。
让 k n-1 ... k 1 k 0 为< em> k 。
让 l 是最小的 i 的索引,这样 k i = 1
我们可以指出,潜在的一对解决方案 x 和 y 必须的所有位都为 i , i
否则,唯一未设置第 i 位的 xy 的唯一方法是使 x i = y i = 1 和 x&y 不会设置其 i 位。
现在,我们到达索引 l 处的第一位。
情况更加复杂,因为我们有几种方法可以在 x-y 的结果中设置该位。
为此,我们必须考虑比特集 l..m ,使得 k i = k i + 1 = k i + 2 = ... = 1 ∀l≤i
例如,如果 l = 0 和 m = 1 ,则 k 的两个LSB为01,我们可以通过以下方法获得此结果:计算01-00(1-0)或10-01(2-1)。无论哪种情况,结果都是正确的(1),并且 x 和 y 的位相反,并且在与运算后为零。
当序列由多个序列组成时,必须对每对连续的序列从LSB进行替换。
这里是一个例子。为简化起见,我们假设序列从第0位开始,但是泛化是立即进行的:
k = 0111
平凡的解决方案 x = k = 0111 y = 0 = 0000
在LSB处将1重写为2-1:将1加到x并将1加到y
x = 0111 + 0001 = 1000 = 8 y = 0000 + 0001 = 0001
将索引1处1的位(2 1 )重写为4-2:将x加2并将y加2
x = 0111 + 0010 = 1011 y = 0000 + 0010 = 0010
将索引2(1 2 )处1处的位重写为4 = 8-4:将x加4并将y加4
x = 0111 + 0100 = 1011 y = 0000 + 0100 = 0100
因此,对于由1后跟零的序列:
Compute the trivial solution where x=<sequence> and y=0
for every one in the sequence
let i be the position of this one
generate a new solution by adding 2^i to x and y of the trivial solution
要恢复,必须以两种顺序分解数字,从LSB开始
*零是连续零的序列
*一是一串一,后跟一个零
通过替换获得结果
*零乘一组零
*通过将0、1、2、4、2 i 添加到平凡解01111..11 / 000 ... 000
示例:
k = 22 = 16+4+2 = 0 0 0 1 0 1 1 0
Rewrite first sequence
011 -> 011/000 (trivial solution)
100/001 (trivial solution+1)
101/010 (trivial solution+2)
Rewrite second sequence
01 -> 01/00 (trivial solution)
10/01 (trivial solution + 1)
And so there are 3*2=6 solutions
010110/000000 22/0
011000/000010 24/2
011010/000100 26/4
100110/010000 38/16
101000/010010 40/18
101010/010100 42/20
答案 1 :(得分:0)
Java实现就是这样...
import java.util.ArrayList;
public class FindPairs {
public static void main(String args[]) {
int arr[] = {1,3,4,5,6,9};
int k = 3;
ArrayList<String> out = new ArrayList<String>();
for(int i=0; i<arr.length; i++) {
for(int j=i+1; j<arr.length; j++) {
if((Math.abs(arr[i]-arr[j]) == k) && ((arr[i]&arr[j]) == 0)) {
out.add("("+arr[i]+","+arr[j]+")");
}
}
}
if(out.size()>0) {
for(String pair:out) {
System.out.println(pair);
}
}else {
System.out.println("No such pair !");
}
}
}