我正在做一些关于按位运算的问题。所以我在想找到 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 个维度:
-
i
:您尝试选择是添加到第一个子序列还是第二个子序列的当前索引。 -
firstXOR
:已添加到第一个子序列的所有元素的异或。
您的DP关系如下:
DP[i][firstXOR]
= min(DP[i+1][firstXOR ^ a[i]]
,DP[i+1][firstXOR]
)
-
DP[i+1][firstXOR ^ a[i]]
表示将当前元素添加到第一个子序列的选择。 -
DP[i+1][firstXOR]
表示将当前元素添加到第二个子序列的选择。
当你达到基态(i == end of the array
)时,你应该返回firstXOR
和secondXOR
之间的差值(secondXOR
是添加到第二个子序列的元素的异或)。
请注意,通过执行以下操作,您可以轻松获取secondXOR
(已添加到第二个子序列的元素的 XOR):
secondXOR
= (数组中所有元素的异或)^(firstXOR
)