http://acm.hdu.edu.cn/showproblem.php?pid=6168
不说了。。too young。。
每次找最小的。然后删掉和a集合中每个数构成的和。
(能够保证每个数的配对都够)
开始用 muliset写的,erase全删除完了,。。发现了一个技巧,挺好用
#include <bits/stdc++.h>
using namespace std;
vector<int>q;
multiset<int>se;
int main()
{ int m,x;
while(~scanf("%d",&m)){
se.clear();
q.clear();
for(int i=0;i<m;i++){
scanf("%d",&x);
se.insert(x);
}
while(se.size()>0){
int u=*se.begin();
//cout<<u<<endl;
se.erase(se.lower_bound(u));
for(int i=0;i<q.size();i++){
se.erase(se.lower_bound(u+q[i]));
}
q.push_back(u);
//cout<<u<<endl;
}
printf("%d\n",q.size());
printf("%d",q[0]);
for(int i=1;i<q.size();i++){
printf(" %d",q[i]);
}
printf("\n");
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
/* 比赛的时候,思路不清晰。。。
想的是类似 哈夫曼树,每次找到两个最小的。删除他们的和。
然后在找第二小的。。(也不知道咋想的。。。)
每次枚举 i和j的时候,
因为i比j小,所以i已经枚举了,但是j没出现。
但是可以 每次都枚举比他小的,这样i每次都是可以枚举完的。。
*/
const int maxn=1e5+4000;
typedef long long ll;
vector<int>q;
int c[maxn];
map<int,int>mp;
int main()
{ int t,m;int x;
while(~scanf("%d",&m)){
q.clear();
memset(c,0,sizeof(c));
mp.clear();
//scanf("%d",&m);
for(int i=0;i<m;i++){
scanf("%d",&x);
q.push_back(x);
mp[x]++;
//cout<<x<<"????"<<endl;
}
sort(q.begin(),q.end());
int siz=0;
//cout<<mp[q[0]]<<endl;
for(int i=0;i<q.size();i++){
if(!mp[q[i]]) continue;
mp[q[i]]--;
//cout<<q[i]<<" "<<mp[q[i]]<<endl;
for(int j=0;j<siz;j++){
mp[q[i]+c[j]]--;
// cout<<q[i]+c[j]<<"del"<<endl;
}
c[siz++]=q[i];
}
printf("%d\n",siz);
printf("%d",c[0]);
for(int i=1;i<siz;i++){
printf(" %d",c[i]);
}
printf("\n");
}
return 0;
}