hdu-6168 Numbers

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;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值