试图找到满足 n + x = n ^ x 的 x 的数量失败并超时
Trying to find the number of x's that satisfies n + x = n ^ x fails with timeout
我正在尝试使用 Java 8 的新功能(例如 Stream
s.
问题描述:
Given an integer, n, find each x such that:
- 0 <= x <= n
- n + x = n ^ x
where ^ denotes the bitwise XOR operator. Then print an integer denoting the total number of x's satisfying the criteria above.
Constraints
- 0 <= n <= 1015
Sample Input: 5
Sample Output: 2
Explanation:
For n = 5, the x values 0 and 2 satisfy the conditions:
- 5 + 0 = 5 ^ 0 = 5
- 5 + 2 = 5 ^ 2 = 7
Thus, we print 2 as our answer.
Sample Input: 10
Sample Output: 4
Explanation:
For n = 10, the x values 0, 1, 4, and 5 satisfy the conditions:
- 10 + 0 = 10 ^ 0 = 10
- 10 + 1 = 10 ^ 1 = 11
- 10 + 4 = 10 ^ 4 = 14
- 10 + 5 = 10 ^ 5 = 15
Thus, we print 4 as our answer.
我的代码如下:
public class SumVsXor
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
long n = in.nextLong();
long count = LongStream.rangeClosed(0, n)
.filter(k -> k + n == (k ^ n))
.count();
System.out.println(count);
}
}
问题是这段代码没有通过所有测试用例。
它适用于 n
的小值,但对于 1000000000000000
这样的大值,它会因超时而失败。
我想知道 LongStream
是否无法处理具有那么多元素的 Stream
。
您的代码存在的问题是效率很低。对于 n==1000000000000000
的情况,您的 Stream
管道正在执行 1,000,000,000,000,000
加法和异或运算,这需要很长时间。测试 0 和 n 之间的每个数字是否 n + x == n ^ x
会花费很长时间,即使您使用 for 循环而不是 Stream
s.
与其检查 0 到 n 之间的所有数字,不如尝试找出一种更好的方法来计算所需的 x 总数。这个问题出现在 "Bit Manipulation" 部分下的事实应该给你一个提示
查看满足
n + x == n ^ x
.
的数字位
让我们考虑一下 n==1000000000000000
的情况。这个大数的二进制表示是
0000000000000011100011010111111010100100110001101000000000000000
=== == = ====== = = = == == =
--- - - - - -- -- --- - ---------------
~~~~~~~~~~~~~~
为了使n + x
等于n ^ x
,x
必须在与1
位对应的所有位中具有0
值n
的(上面用 =
标记),以及与 n
的 0
位相对应的位中的 0
或 1
值(上面标有 -
)。这不包括前导 0
s(上面标记为 ~
),因为 x 必须 <= n
,因此 [=24= 中的任何前导 0
s ] 还必须在 x
中有一个 0
值。
这意味着n + x == n ^ x
的x的总数是
2n
中0
的个数,不包括前导 0
s.
在n = 1000000000000000
的情况下,有30
个这样的0
位,所以满足要求的x
的总数是230.
这是计算 x
总数的一种方法:
long n = 1000000000000000L;
int zeroBitsCount = 0;
while (n > 0) {
if (n % 2 == 0) {
zeroBitsCount++; // counts the number of non-leading 0 bits
}
n = n >> 1; // divide n by 2 in order to examine the next bit in the next iteration
}
long total = 1L << zeroBitsCount; // the total is 2^(the 0 bits count)
public static void main (String[] args) {
Scanner in = new Scanner (System.in);
long n = in.nextLong();
long count = 1L << (64-Long.bitCount(n)-Long.numberOfLeadingZeros(n));
System.out.println(count);
}
如果你对 XOR 了解不多,这道题很简单。我对java了解不多。但我可以在 python.
中解释
1.First 将数字转换为二进制。
2.Count 该二进制数中零的个数。
3.print 2 ^(零的数量)就是这样。
这是我的 python 代码。
n = int(input())
sum = 0
if n!=0:
n=str(bin(n))
for i in range(len(n)):
if n[i]=='0':
sum = sum + 1
print(2**(sum-1))
else: print(1)
将总和减1的原因是,在python中它将数字转换为二进制格式。例如:0b'10101。
我得到了同样的结果,但是通过不同的解释,所以我想我可以 post 在这里。
Eran 的回答得出了与我相同的结论:修改初始数字的二进制表示中的零 - 这非常简单。
假设我们的号码是
101010100
所以它有 5 个零。
您需要所有可能的组合:
- 一个零
- 两个零
- 三个零
- 四个零
- 五个零
实际上是:
comb(1,5) + comb(2,5) + comb(3,5) + comb(4,5) + comb (5,5)
这是一个众所周知的公式,等于:
pow(2,n) // where n is five in our case
从那里解决方案很明显...
我正在尝试使用 Java 8 的新功能(例如 Stream
s.
问题描述:
Given an integer, n, find each x such that:
- 0 <= x <= n
- n + x = n ^ x
where ^ denotes the bitwise XOR operator. Then print an integer denoting the total number of x's satisfying the criteria above.
Constraints
- 0 <= n <= 1015
Sample Input: 5
Sample Output: 2
Explanation:
For n = 5, the x values 0 and 2 satisfy the conditions:
- 5 + 0 = 5 ^ 0 = 5
- 5 + 2 = 5 ^ 2 = 7
Thus, we print 2 as our answer.
Sample Input: 10
Sample Output: 4
Explanation: For n = 10, the x values 0, 1, 4, and 5 satisfy the conditions:
- 10 + 0 = 10 ^ 0 = 10
- 10 + 1 = 10 ^ 1 = 11
- 10 + 4 = 10 ^ 4 = 14
- 10 + 5 = 10 ^ 5 = 15
Thus, we print 4 as our answer.
我的代码如下:
public class SumVsXor
{
public static void main(String[] args)
{
Scanner in = new Scanner(System.in);
long n = in.nextLong();
long count = LongStream.rangeClosed(0, n)
.filter(k -> k + n == (k ^ n))
.count();
System.out.println(count);
}
}
问题是这段代码没有通过所有测试用例。
它适用于 n
的小值,但对于 1000000000000000
这样的大值,它会因超时而失败。
我想知道 LongStream
是否无法处理具有那么多元素的 Stream
。
您的代码存在的问题是效率很低。对于 n==1000000000000000
的情况,您的 Stream
管道正在执行 1,000,000,000,000,000
加法和异或运算,这需要很长时间。测试 0 和 n 之间的每个数字是否 n + x == n ^ x
会花费很长时间,即使您使用 for 循环而不是 Stream
s.
与其检查 0 到 n 之间的所有数字,不如尝试找出一种更好的方法来计算所需的 x 总数。这个问题出现在 "Bit Manipulation" 部分下的事实应该给你一个提示
查看满足
n + x == n ^ x
.
让我们考虑一下 n==1000000000000000
的情况。这个大数的二进制表示是
0000000000000011100011010111111010100100110001101000000000000000
=== == = ====== = = = == == =
--- - - - - -- -- --- - ---------------
~~~~~~~~~~~~~~
为了使n + x
等于n ^ x
,x
必须在与1
位对应的所有位中具有0
值n
的(上面用 =
标记),以及与 n
的 0
位相对应的位中的 0
或 1
值(上面标有 -
)。这不包括前导 0
s(上面标记为 ~
),因为 x 必须 <= n
,因此 [=24= 中的任何前导 0
s ] 还必须在 x
中有一个 0
值。
这意味着n + x == n ^ x
的x的总数是
2n
中0
的个数,不包括前导 0
s.
在n = 1000000000000000
的情况下,有30
个这样的0
位,所以满足要求的x
的总数是230.
这是计算 x
总数的一种方法:
long n = 1000000000000000L;
int zeroBitsCount = 0;
while (n > 0) {
if (n % 2 == 0) {
zeroBitsCount++; // counts the number of non-leading 0 bits
}
n = n >> 1; // divide n by 2 in order to examine the next bit in the next iteration
}
long total = 1L << zeroBitsCount; // the total is 2^(the 0 bits count)
public static void main (String[] args) {
Scanner in = new Scanner (System.in);
long n = in.nextLong();
long count = 1L << (64-Long.bitCount(n)-Long.numberOfLeadingZeros(n));
System.out.println(count);
}
如果你对 XOR 了解不多,这道题很简单。我对java了解不多。但我可以在 python.
中解释1.First 将数字转换为二进制。 2.Count 该二进制数中零的个数。 3.print 2 ^(零的数量)就是这样。
这是我的 python 代码。
n = int(input())
sum = 0
if n!=0:
n=str(bin(n))
for i in range(len(n)):
if n[i]=='0':
sum = sum + 1
print(2**(sum-1))
else: print(1)
将总和减1的原因是,在python中它将数字转换为二进制格式。例如:0b'10101。
我得到了同样的结果,但是通过不同的解释,所以我想我可以 post 在这里。
Eran 的回答得出了与我相同的结论:修改初始数字的二进制表示中的零 - 这非常简单。
假设我们的号码是
101010100
所以它有 5 个零。
您需要所有可能的组合:
- 一个零
- 两个零
- 三个零
- 四个零
- 五个零
实际上是:
comb(1,5) + comb(2,5) + comb(3,5) + comb(4,5) + comb (5,5)
这是一个众所周知的公式,等于:
pow(2,n) // where n is five in our case
从那里解决方案很明显...