📌  相关文章
📜  查找数组使得没有子数组具有异或零或 Y

📅  最后修改于: 2022-05-13 01:57:51.686000             🧑  作者: Mango

查找数组使得没有子数组具有异或零或 Y

给定两个整数X (1 ≤ X ≤ 15) 和Y 。任务是找到一个最大可能长度N的数组,使得数组中的所有元素都位于12 X之间,并且不存在子数组,使得子数组的 xor 值为0Y 。如果存在多个答案,则打印其中任何一个。如果不存在这样的数组,则打印-1
例子:

方法:主要思想是构建所需数组的前缀异或,然后从中构建数组。让前缀异或数组为pre[]
现在,前缀数组中任意两对的 XOR (pre[l] ^ pre[r])将表示原始数组的某个子数组的 XOR,即arr[l + 1] ^ arr[l + 2] ^ ... ^ arr[r]
因此,问题现在简化为从pre[]数组的元素构造一个数组,使得没有任何元素对的按位异或等于0Y ,并且它的长度应该是最大的。
请注意,没有任何一对数字的按位异或和等于 0仅仅意味着不能使用相同的数字两次
如果Y ≥ 2 X则没有任何小于2 X的数字对具有等于Y的按位异或,因此您可以按任意顺序使用从12 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