题目
分析
官方题解
和HDU 6092很类似,不过区别在于6092那道题目可以取多个不同的数字组成一个新的数,所以要用0-1背包。这道题目只能取两个数字组成一个新的数,所以用一个
map
维护能够组成的数字就行了,每找到一个新的数字,就遍历之前所有的数来更新
map
。虽然代码看起来是三重循环,但是复杂度是
O(M+N2)
。
代码
#include <cstring>
#include <cstdio>
#include <vector>
#include <map>
using namespace std;
const int N = 125255;
map<int, int> M1;
map<int, int> M2;
int b[N], m;
int a[N], n;
int main()
{
//freopen("test.txt", "r", stdin);
//freopen("out.txt", "w", stdout);
while (~scanf("%d", &m))
{
M1.clear();
M2.clear();
for (int i = 1; i <= m; i++)
{
scanf("%d", &b[i]);
M1[b[i]]++;
}
n = 0;
for (map<int, int>::iterator it = M1.begin(); it != M1.end(); it++)
{
int val = it->first;
int cnt1 = it->second;
int cnt2;
if (!M2.count(val)) cnt2 = 0;
else cnt2 = M2[val];
int cnt3 = cnt1 - cnt2;
for (int j = 1; j <= cnt3; j++)
{
a[++n] = val;
for (int k = 1; k < n; k++)
M2[val + a[k]]++;
}
}
printf("%d\n", n);
for (int i = 1; i <= n; i++)
printf("%d%c", a[i], i < n ? ' ' : '\n');
}
return 0;
}
本文针对HDU6168题进行详细解析,该题与HDU6092类似,但限制了仅能从输入中选择两个数字组合成新数。采用map数据结构记录所有可能的组合,通过双重循环实现高效更新。最终输出所有可行的组合数量及具体数值。
3万+

被折叠的 条评论
为什么被折叠?



