查找数组使得没有子数组具有异或零或 Y
给定两个整数X (1 ≤ X ≤ 15) 和Y 。任务是找到一个最大可能长度N的数组,使得数组中的所有元素都位于1和2 X之间,并且不存在子数组,使得子数组的 xor 值为0或Y 。如果存在多个答案,则打印其中任何一个。如果不存在这样的数组,则打印-1
例子:
Input: X = 3, Y = 5
Output: 1 3 1
(1 ^ 3) = 2
(3 ^ 1) = 2
(1 ^ 3 ^ 1) = 3
Input: X = 1, Y = 1
Output: -1
方法:主要思想是构建所需数组的前缀异或,然后从中构建数组。让前缀异或数组为pre[] 。
现在,前缀数组中任意两对的 XOR (pre[l] ^ pre[r])将表示原始数组的某个子数组的 XOR,即arr[l + 1] ^ arr[l + 2] ^ ... ^ arr[r] 。
因此,问题现在简化为从pre[]数组的元素构造一个数组,使得没有任何元素对的按位异或等于0或Y ,并且它的长度应该是最大的。
请注意,没有任何一对数字的按位异或和等于 0仅仅意味着不能使用相同的数字两次。
如果Y ≥ 2 X则没有任何小于2 X的数字对具有等于Y的按位异或,因此您可以按任意顺序使用从1到2 X – 1的所有数字。否则,您可以考虑形成对的数字,其中每对由2 个数字组成,按位异或和等于Y 。从任何一对中,如果您将一个数字添加到数组中,则无法添加另一个。但是,这些对是相互独立的:您在一对中的选择不会影响任何其他对。因此,您可以选择任何一对中的任何一个数字,然后按您想要的任何顺序添加它们。构造数组pre[]后,可以使用以下方法构造原始数组: arr[i] = pre[i] ^ pre[i – 1]。
下面是上述方法的实现:
C++
// C++ implementation of the approach
#include
using namespace std;
// Function to find the maximum length array
void maxLengthArr(int x, int y)
{
// To store if an element is
// already taken or not
bool ex[(1 << x)];
// To store visited numbers
ex[0] = 1;
vector pre({ 0 });
// For all possible values of pre[]
for (int i = 1; i < (1 << x); i++) {
// If it is already taken
if (ex[i ^ y])
continue;
pre.push_back(i);
ex[i] = 1;
}
// Not possible
if (pre.size() == 1) {
cout << "-1";
return;
}
// Print the array constructing it
// from the prefix-xor array
for (int i = 1; i < pre.size(); i++)
cout << (pre[i] ^ pre[i - 1]) << " ";
}
// Driver code
int main()
{
int X = 3, Y = 5;
maxLengthArr(X, Y);
return 0;
}
Java
// Java implementation of the approach
import java.util.*;
class GFG
{
// Function to find the maximum length array
static void maxLengthArr(int x, int y)
{
// To store if an element is
// already taken or not
boolean[] ex = new boolean[(1 << x)];
// To store visited numbers
ex[0] = true;
Vector pre = new Vector();
pre.add(0);
// For all possible values of pre[]
for (int i = 1; i < (1 << x); i++)
{
// If it is already taken
if (ex[i ^ y])
continue;
pre.add(i);
ex[i] = true;
}
// Not possible
if (pre.size() == 1)
{
System.out.print("-1");
return;
}
// Print the array constructing it
// from the prefix-xor array
for (int i = 1; i < pre.size(); i++)
System.out.print((pre.get(i) ^
pre.get(i - 1)) + " ");
}
// Driver code
public static void main(String[] args)
{
int X = 3, Y = 5;
maxLengthArr(X, Y);
}
}
// This code is contributed by 29AjayKumar
Python3
# Python3 implementation of the approach
# Function to find the maximum length array
def maxLengthArr(x, y) :
# To store if an element is
# already taken or not
ex = [0] * (1 << x);
# To store visited numbers
ex[0] = 1;
pre = [0];
# For all possible values of pre[]
for i in range(1, (1 << x)) :
# If it is already taken
if (ex[i ^ y]) :
continue;
pre.append(i);
ex[i] = 1;
# Not possible
if (len(pre) == 1) :
print("-1", end = "");
return;
# Print the array constructing it
# from the prefix-xor array
for i in range(1, len(pre)) :
print(pre[i] ^ pre[i - 1], end = " ");
# Driver code
if __name__ == "__main__" :
X = 3; Y = 5;
maxLengthArr(X, Y);
# This code is contributed by AnkitRai01
C#
// C# implementation of the approach
using System;
using System.Collections.Generic;
class GFG
{
// Function to find the maximum length array
static void maxLengthArr(int x, int y)
{
// To store if an element is
// already taken or not
bool[] ex = new bool[(1 << x)];
// To store visited numbers
ex[0] = true;
var pre = new List();
pre.Add(0);
// For all possible values of pre[]
for (int i = 1; i < (1 << x); i++)
{
// If it is already taken
if (ex[i ^ y])
continue;
pre.Add(i);
ex[i] = true;
}
// Not possible
if (pre.Count == 1)
{
Console.Write("-1");
return;
}
// Print the array constructing it
// from the prefix-xor array
for (int i = 1; i < pre.Count; i++)
Console.Write((pre[i] ^ pre[i - 1]) + " ");
}
// Driver code
public static void Main(String[] args)
{
int X = 3, Y = 5;
maxLengthArr(X, Y);
}
}
// This code is contributed by
// sanjeev2552
Javascript
1 3 1