相邻对的最小可能最大异或的排列计数
给定一个整数N ,考虑一个数组,其元素在[0, N-1]范围内,使得所有相邻对的最大按位异或在数组的所有可能排列中最小。找出这种排列的数量。
例子:
Input: N = 3
Output: 2
Explanation:
A[] = {2, 0, 1}, Maximum of XOR(2, 0) and XOR(0, 1) is 2
A[] = {1, 0, 2}, Maximum of XOR(1, 0) and XOR(0, 2) is 2
All other permutations of the array have maximum XOR greater than
2, hence the above two are the only permutations with the minimum XOR.
Input: N = 5
Output: 12
Explanation: The permutations are:
{1, 2, 3, 0, 4}, {1, 3, 2, 0, 4}, {2, 1, 3, 0, 4}, {3, 2, 1, 0, 4}, {3, 1, 2, 0, 4}, {2, 3, 1, 0, 4},
{4, 0, 1, 2, 3}, {4, 0, 1, 3, 2}, {4, 0, 2, 3, 1}, {4, 0, 2, 1, 3}, {4, 0, 3, 1, 2}, {4, 0, 3, 2, 1}.
All these permutations have maximum value of XOR as 4 which is the minimum possible.
方法:如果所有元素都以它们的二进制表示形式编写,则可以根据谁拥有最大可能的最左设置位集的条件将它们分为两组。因此,一组将具有最大可能的最左边位设置的元素,而另一组将包含剩余的元素。以下是解决问题的主要观察:
- The key observation here is that the maximum XOR will occur when the adjacent pairs are from two different groups,
- So to minimize the maximum, the permutation has to be such that there is only one adjacent pair whose elements are from different groups and that key pair will consist of 0 and the highest integral power of 2 before N. As the power of 2 will have only 1-bit set as compared to all integers greater than it and 0, of course, has no bit-set they make the perfect optimal pair.
- Elements of the same group will remain on the same side of the key pair i.e. elements with most significant bits set stay on the side of highest integral power of 2 and the others on the opposite side.
- The final answer = number of permutations on the left of key pair * number of permutations on the right of key pair * 2.
按照下面提到的步骤来实现上述观察:
- 找到最大可能的最左边 setbit 。
- 现在计算每个组中的元素数量。
- 找到密钥对。
- 计算每边的排列,然后将它们相互乘以2 。
- 返回这个相乘的值作为答案。
下面是上述算法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
// Function to find factorial of a number
int factorial(int x)
{
int ans = 1;
while (x > 0) {
ans = ans * x;
x--;
}
return ans;
}
// Function to find the MSB of a number
int mostSigBit(int x)
{
int msb = -1;
while (x != 0) {
x = x >> 1;
msb++;
}
return msb;
}
// Function to calculate number of possible
// permutations with minimum bitwise XOR
int minXor(int N)
{
int highest_bit = mostSigBit(N - 1);
// The highest power of 2 before
// the largest number which will
// be part of the key pair with 0
int key = 1 << highest_bit;
// Count of elements in group 1
int grp1 = 0;
// Count of elements in group 2
int grp2 = 0;
for (int i = 1; i < N; i++) {
if (i > key)
grp2++;
else if (i < key)
grp1++;
}
int ans = (factorial(grp1)
* factorial(grp2))
* 2;
return ans;
}
// Driver code
int main()
{
int N = 5;
// Function call
int ans = minXor(N);
cout << ans;
return 0;
}
Java
// Java program for the above approach
import java.util.*;
public class GFG {
// Function to find factorial of a number
static int factorial(int x)
{
int ans = 1;
while (x > 0) {
ans = ans * x;
x--;
}
return ans;
}
// Function to find the MSB of a number
static int mostSigBit(int x)
{
int msb = -1;
while (x != 0) {
x = x >> 1;
msb++;
}
return msb;
}
// Function to calculate number of possible
// permutations with minimum bitwise XOR
static int minXor(int N)
{
int highest_bit = mostSigBit(N - 1);
// The highest power of 2 before the
// largest number which will be
// part of the key pair with 0
int key = 1 << highest_bit;
// Count of elements in group 1
int grp1 = 0;
// Count of elements in group 2
int grp2 = 0;
for (int i = 1; i < N; i++) {
if (i > key)
grp2++;
else if (i < key)
grp1++;
}
int ans = (factorial(grp1)
* factorial(grp2))
* 2;
return ans;
}
// Driver code
public static void main(String[] args)
{
int N = 5;
// Function call
int ans = minXor(N);
System.out.println(ans);
}
}
Python3
# Python code for the above approach
# Function to find factorial of a number
def factorial(x):
ans = 1;
while (x > 0):
ans = ans * x;
x -= 1
return ans;
# Function to find the MSB of a number
def mostSigBit(x):
msb = -1;
while (x != 0):
x = x >> 1;
msb += 1
return msb;
# Function to calculate number of possible
# permutations with minimum bitwise XOR
def minXor(N):
highest_bit = mostSigBit(N - 1);
# The highest power of 2 before
# the largest number which will
# be part of the key pair with 0
key = 1 << highest_bit;
# Count of elements in group 1
grp1 = 0;
# Count of elements in group 2
grp2 = 0;
for i in range(1, N) :
if (i > key):
grp2 += 1
elif (i < key):
grp1 += 1
ans = (factorial(grp1) * factorial(grp2)) * 2
return ans;
# Driver code
N = 5;
# Function call
ans = minXor(N);
print(ans);
# This code is contributed by Saurabh jaiswal
C#
// C# program for the above approach
using System;
class GFG {
// Function to find factorial of a number
static int factorial(int x)
{
int ans = 1;
while (x > 0) {
ans = ans * x;
x--;
}
return ans;
}
// Function to find the MSB of a number
static int mostSigBit(int x)
{
int msb = -1;
while (x != 0) {
x = x >> 1;
msb++;
}
return msb;
}
// Function to calculate number of possible
// permutations with minimum bitwise XOR
static int minXor(int N)
{
int highest_bit = mostSigBit(N - 1);
// The highest power of 2 before the
// largest number which will be
// part of the key pair with 0
int key = 1 << highest_bit;
// Count of elements in group 1
int grp1 = 0;
// Count of elements in group 2
int grp2 = 0;
for (int i = 1; i < N; i++) {
if (i > key)
grp2++;
else if (i < key)
grp1++;
}
int ans = (factorial(grp1)
* factorial(grp2))
* 2;
return ans;
}
// Driver code
public static void Main()
{
int N = 5;
// Function call
int ans = minXor(N);
Console.WriteLine(ans);
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
12
时间复杂度: O(N 2 )
辅助空间: O(1)