题意:一个a数列,对于每一个(i,j) 1<=i<j<=n,做和,形成b数列,b所以有n*(n-1)/2个数字,a有n个,现在把a,b混合成c,求a
思路:排序后,可以知道,a[1]=c[1],a[2]=c[2],然后我们可以把a[1]+a[2]放入优先队列中,看是a[3]小还是a[1]+a[2],得到a[3],再放入他与前面数字的和。。递推可得到a
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=125255; 5 6 ll a[N]; 7 ll b[N]; 8 9 struct node{ 10 ll x; 11 node(ll zz){ 12 x=zz; 13 } 14 friend bool operator <(node xx,node y){ 15 return xx.x>y.x; 16 } 17 }; 18 priority_queue<node>p; 19 int main(){ 20 int n; 21 while(scanf("%d",&n)!=EOF){ 22 for(int i=1;i<=n;i++) scanf("%lld",&b[i]); 23 sort(b+1,b+1+n); 24 a[1]=b[1];a[2]=b[2]; 25 p.push(node(a[1]+a[2])); 26 int l=3; 27 ll x; 28 for(int i=3;i<=n;i++){ 29 int tt=0; 30 if(!p.empty()){ 31 x=p.top().x;tt=1; 32 } 33 if(b[i]==x&&tt) { 34 p.pop(); 35 } 36 else { 37 for(int j=1;j<l;j++){ 38 p.push(node(b[i]+a[j])); 39 } 40 a[l]=b[i];l++; 41 } 42 } 43 cout<<l-1<<endl; 44 for(int i=1;i<l;i++){ 45 printf("%d",a[i]); 46 if(i==l-1) printf(" "); 47 else printf(" "); 48 } 49 } 50 return 0; 51 }
用减去的想法更简单些
1 #include<bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=125255; 5 6 ll a[N]; 7 ll b[N]; 8 9 map<ll ,int >ma; 10 11 int main(){ 12 int n; 13 while(scanf("%d",&n)!=EOF){ 14 ma.clear(); 15 for(int i=1;i<=n;i++) scanf("%lld",&b[i]),ma[b[i]]++; 16 sort(b+1,b+1+n); 17 a[1]=b[1];a[2]=b[2]; 18 int l=3; 19 ma[a[1]]--;ma[a[2]]--;ma[a[1]+a[2]]--; 20 for(int i=3;i<=n;i++){ 21 if(ma[b[i]]!=0){ 22 for(int j=1;j<l;j++) 23 ma[b[i]+a[j]]--; 24 a[l]=b[i];l++; 25 ma[b[i]]--; 26 } 27 } 28 cout<<l-1<<endl; 29 for(int i=1;i<l;i++){ 30 printf("%lld",a[i]); 31 if(i==l-1) printf(" "); 32 else printf(" "); 33 } 34 } 35 return 0; 36 }