给定long int x ,计算满足以下条件的 a 的值的数量:
a XOR x > x
0< a < X
其中 a 和 x 是长整数, XOR 是按位XOR运算符
你将如何解决这个问题?
我还应该提到输入x可以大到10 ^ 10
我设法通过迭代0到x检查条件并递增计数值来获得强力解决方案..但这不是最佳解决方案......
这是我试过的蛮力。它可以工作,但对于大的x值来说非常慢。
for(int i =0; i < x; i++)
{
if((0 < i && i < x) && (i ^ x) > x)
count++;
}
答案 0 :(得分:4)
long long NumberOfA(long long x)
{
long long t = x <<1;
while(t^(t&-t)) t ^= (t&-t);
return t-++x;
}
long long x = 10000000000;
printf("%lld ==> %lld\n", 10LL, NumberOfA(10LL) );
printf("%lld ==> %lld\n", x, NumberOfA(x) );
<强> 输出 强>
10 ==> 5
10000000000 ==> 7179869183
尝试解释逻辑(使用示例10或1010b
)
10100b
)10000b
)16 - 11 == 5
)<小时/> 试图解释
您的规则是a ^ x
必须大于x
,但您无法将额外位添加到a
或x
。
(如果从4位值开始,则只能使用4位)
N位数字的最大可能值是2^n -1
(例如,4位数,2 ^ 4-1 == 15)
让我们拨打这个号码 B 。
在您的值x
和 B (含)之间,有 B - x
个可能值。
(回到我的示例,10。在15到10之间,有5个可能的值:11
,12
,13
,14
,{{1} })
在我的代码中,15
为t
,然后关闭所有低位
(x << 1
为10 << 1
;关闭所有低位以获取20
)
然后16
B , B - x就是您的回答:
(16 - 1
与t - 1 - x,
相同,是答案)
答案 1 :(得分:4)
考虑这一点的一种方法是考虑 x 中的每个位。
long f(long const x)
{
// only positive x can have non-zero result
if (x <= 0) return 0;
long count = 0;
// Iterate from LSB to MSB
for (long mask = 1; mask < x; mask <<= 1)
count += x & mask
? 0
: mask;
return count;
}
我们可能怀疑这里有一个模式 - 看起来我们只是复制 x 并翻转其位。
让我们确认一下,使用最小的测试程序:
#include <cstdlib>
#include <iostream>
int main(int, char **argv)
{
while (*++argv)
std::cout << *argv << " -> " << f(std::atol(*argv)) << std::endl;
}
0 -> 0
1 -> 0
2 -> 1
3 -> 0
4 -> 3
5 -> 2
6 -> 1
7 -> 0
8 -> 7
9 -> 6
10 -> 5
11 -> 4
12 -> 3
13 -> 2
14 -> 1
15 -> 0
所以我们所要做的就是'涂抹'这个值,以便设置最重要的1之后的所有零位,然后xor:
long f(long const x)
{
if (x <= 0) return 0;
long mask = x;
while (mask & (mask+1))
mask |= mask+1;
return mask ^ x;
}
这要快得多,而且还是O(log n)。