给定一个非负整数N ,任务是找到两个整数A(小于N的最大整数)和(大于N的最小整数),使得A + N = A ^ N且B + N = B ^ N
例子:
Input: N = 5
Output: A = 2 and B = 8
2 + 8 = 2 ^ 8 = 10
Input: N = 10
Output: A = 5 and B = 16
5 + 16 = 5 ^ 16 = 21
方法:让我们分别找到A和B。要解决此问题,我们必须使用属性x + y = x ^ y + 2 *(x&y)
由于问题表明xor之和等于给定的总和,这意味着它们的AND必须为0。
- 查找A: N可以表示为一系列0和1的位。要找到A,我们首先必须找到已设置的N的最高有效位。因为A&N = 0,所以N设置位的位置,对于那些位置,我们将A的位设为未设置;对于N位置的设置,我们将对该位进行设置,以使A最大化。我们将对从最高有效位到最低有效位的所有位进行处理。因此,我们将获得A。
- 查找B:查找B很容易。令我为1中最左置位的位置。我们希望B大于N,我们也希望B&N = 0。因此,使用这两个事实,B将始终为(1 <<(i + 1))。
下面是上述方法的实现:
// C++ implementation of the approach
#include
using namespace std;
#define MAX 32
// Function to find A and B
void findAB(int N)
{
bitset arr(N), brr(N);
// To store the leftmost set bit in N
int leftsetN = -1;
for (int i = MAX - 1; i >= 0; --i) {
if (arr[i] == 1) {
leftsetN = i;
break;
}
}
// To store the value of A
int A = 0;
for (int i = leftsetN; i >= 0; --i) {
// If the bit is unset in N
// then we will set it in A
if (arr[i] == 0) {
A |= (1 << i);
}
}
// To store the value of B
int B = 0;
// B will be (1 << (leftsetN + 1))
B = 1 << (leftsetN + 1);
// Print the values of A and B
cout << "A = " << A << " and B = " << B;
}
// Driver code
int main()
{
int N = 5;
findAB(N);
return 0;
}
输出:
A = 2 and B = 8