将数组拆分为两个子序列,使得子序列的xor值之间的差异最小

时间:2017-09-02 04:11:36

标签: bitwise-operators

我正在做一些关于按位操作的问题。所以我在想什么是找到xor值(覆盖整个数组的两个非重叠的子序列)之间差异的最快方法。我找不到解决这个问题的快捷方法。我认为解决这个问题会非常有趣。我希望任何人都可以提出快速的解决方案并分享这篇文章。

我为我糟糕的英语道歉:)

2 个答案:

答案 0 :(得分:3)

我假设我们必须将给定的数组拆分成两个子数组,这样一个子数组的元素的xor和其他子数组的元素之间的差异是最小的。

int main() {
int n,*a;
cin>>n;
a = new int[n];
for(int i=0;i<n;i++) {
    cin>>a[i];
}
int total_xor=0;
for(int i=0;i<n;i++) {
    total_xor ^=a[i]; 
}
int min_diff = 1000000009,part_xor=0,split_index=0,i;
for(i=0;i<n;i++) {
    total_xor^=a[i];
    part_xor^=a[i];
    if((abs(total_xor-part_xor))<min_diff) {
        min_diff=abs(total_xor-part_xor);
        split_index = i;
    }
    //cout<<abs(total_xor-part_xor)<<"\n";
}
cout<<"First subarray 1 to "<<split_index+1<<"\n";
cout<<"Second subarray "<<(split_index+2)<<" to "<<n<<"\n";
}

答案 1 :(得分:1)

如果通过子序列表示连续的子阵列,那么Sanjeevkumar的答案就足够了。

但是,如果你的意思是你需要将数组拆分成两个数组,而不是它们都是由连续范围组成的,那么我想到的最简单的解决方案就是使用动态编程。

您的 DP 数组需要有2个维度:

  1. i:您尝试选择是否添加到第一个或第二个子序列的当前索引。

  2. firstXOR:已添加到第一个子序列的所有元素的XOR。

  3. 您的 DP 关系如下:

    DP[i][firstXOR] = min( DP[i+1][firstXOR ^ a[i]] DP[i+1][firstXOR]

    1. DP[i+1][firstXOR ^ a[i]]表示将当前元素添加到第一个子序列的选择。

    2. DP[i+1][firstXOR]表示将当前元素添加到第二个子序列的选择。

    3. 当您到达基本州(i == end of the array)时,您应该返回firstXORsecondXOR之间的差异(secondXOR是添加到第二个子序列的元素的XOR )。

      请注意,您可以通过执行以下操作轻松获取secondXOR(已添加到第二个子序列的元素的XOR):

      secondXOR =(数组中所有元素的XOR) ^ firstXOR