Numbers
题意:给一组数,包括了a数组和b数组,并且已知b数组是由a数组里的数两两相加得到的,求a数组。
思路:想到输入的数组里的最小的两个数肯定不在b数组里,即在a数组里,所以:我们先把最小的两个数放进a数组,然后将两个数组相加得到一个数,把这个数去将输入的数组里的一样的数去掉一个,然后再从里面调一个数出来,将它与a数组里所有的元素相加,得到一些数,然后用这些书去掉输入数组里的数。最后就可以得到a数组了。
#include <cstdio>
#include <iostream>
#include <string.h>
#include <string>
#include <map>
#include <queue>
#include <vector>
#include <set>
#include <algorithm>
#include <math.h>
#include <cmath>
#include <stack>
#define mem0(a) memset(a,0,sizeof(a))
#define meminf(a) memset(a,0x3f,sizeof(a))
#define LL long long
#define siz 2505
using namespace std;
int m;
int gp[125255];
//int p[125255];
int ans[125255];
//int tx[125255];
void solve(){
priority_queue<int,vector<int>,greater<int> > que;
int n = 0;
int s = 1,e = 2;
int zx = 0,i = 3,op = 1;
//p[++zx] = gp[s] + gp[e];
que.push(gp[s] + gp[e]);
ans[++n] = gp[s];
ans[++n] = gp[e];
// cout<<1<<endl;
// int tt = 0;
//tx[++tt] = gp[s],tx[++tt] = gp[e];
s = e;
while(i<=m){
// cout<<i<<"----"<<op<<endl;
while(i<=m&&!que.empty()){
int u = que.top();
// cout<<op<<" "<<i<<" "<<gp[i]<<" "<<u<<" "<<endl;
if(u == gp[i]){
++i; que.pop();}
else break;
}
if(i>m) break;
//cout<<op<<endl;
// s = i;
//ans[++n] = gp[i];
//cout<<"---------"<<gp[i]<<"-----------"<<endl;
for(int j = 1;j<=n;j++){
//p[++zx] = ans[j] + gp[i];
que.push(ans[j] + gp[i]);
//cout<<ans[j] + gp[i]<<" -----------"<<endl;
}
//cout<<n<<"&&&&&&&&&&&&&&&&&&&&&"<<i<<" "<<gp[i]<<endl;
ans[++n] = gp[i];
++i;
}
printf("%d\n%d",n,ans[1]);
for(int i=2;i<=n;i++){
printf(" %d",ans[i]);
}
printf("\n");
}
int main()
{
while(~scanf("%d",&m)){
for(int i=1;i<=m;i++){
scanf("%d",&gp[i]);
}
sort(gp+1,gp+m+1);
solve();
}
return 0;
}