题目
分析
官方题解
和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;
}