我正在做一些关于按位操作的问题。所以我在想什么是找到xor值(覆盖整个数组的两个非重叠的子序列)之间差异的最快方法。我找不到解决这个问题的快捷方法。我认为解决这个问题会非常有趣。我希望任何人都可以提出快速的解决方案并分享这篇文章。
我为我糟糕的英语道歉:)
答案 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个维度:
i
:您尝试选择是否添加到第一个或第二个子序列的当前索引。
firstXOR
:已添加到第一个子序列的所有元素的XOR。
您的 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
是添加到第二个子序列的元素的XOR )。
请注意,您可以通过执行以下操作轻松获取secondXOR
(已添加到第二个子序列的元素的XOR):
secondXOR
=(数组中所有元素的XOR) ^ (firstXOR
)