确定一个给定的集合是否可以分割为两个子集,满足两个子集中的元素之和相同,第一行一个整数t表示测试用例数,对每个测试用例,输入一个整数n表示集合中元素个数,接下来输入n个整数,针对每个测试用例,可以分割则输出true,否则输出false,末行有换行。
时间: 2024-10-01 11:03:47 浏览: 52
这是一个经典的动态规划问题,通常称为“分治和哈希”(Divide and Conquer with Hashing)或“3SUM”的变种,用于判断一个数组是否有两个非重复元素之和等于第三个元素。这个问题可以通过使用哈希表(unordered_set)来解决,它的查找时间复杂度接近O(1)。
下面是C++代码的实现:
```cpp
#include <iostream>
#include <unordered_set>
bool canPartition(int* nums, int n) {
std::unordered_set<int> targetSum(nums, nums+n);
int sum = 0;
for (int num : nums) {
sum += num;
}
if (sum % 2 != 0) { // 如果总和是奇数,无法完全平分,返回false
return false;
}
sum /= 2; // 将总和减半,变为我们需要找到的另一个数
// 检查nums中的元素是否存在targetSum中
for (int i = 0; i < n; ++i) {
if (targetSum.find(sum - nums[i]) != targetSum.end()) {
return true;
}
}
return false;
}
int main() {
int t;
std::cin >> t;
while (t--) {
int n;
std::cin >> n;
int* nums = new int[n];
for (int i = 0; i < n; ++i) {
std::cin >> nums[i];
}
bool result = canPartition(nums, n);
std::cout << (result ? "true\n" : "false\n");
delete[] nums; // 注意释放内存
}
return 0;
}
```
这个代码首先检查整个数组的和是否能被2整除,如果不能,则直接返回false。然后,它计算一半的目标值(即我们需要找的另一个元素的和)。接着遍历数组,对于每一个元素,看目标差值(当前元素与目标的一半)是否在哈希表中,如果有就找到了一对符合条件的元素,返回true;遍历结束后仍未找到这样的对,返回false。
阅读全文