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

  • 本文关键字:xor 数组 之间 两个 拆分 bitwise-operators
  • 更新时间 :
  • 英文 :


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

我为我的英语:)不好道歉

我假设我们必须将给定的数组拆分为两个子数组,以便一个子数组的元素的 xor 与其他子数组的元素的 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";
}

如果你所说的子序列是指连续的子数组,那么Sanjeevkumar的答案就足够了。

但是,如果您的意思是需要将数组拆分为两个数组,而没有条件是它们都是由连续范围形成的,那么我想到的最简单的解决方案是使用动态规划。

DP阵列需要具有 2 个维度:

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

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

您的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]表示将当前元素添加到第二个子序列的选择。

当你达到基态(i == end of the array)时,你应该返回firstXORsecondXOR之间的差值(secondXOR是添加到第二个子序列的元素的异或)。

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

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

最新更新