HDU

来源:互联网 发布:share.js用法 编辑:程序博客网 时间:2024/06/01 23:25

题目大意:

有一个a数组,将它的任意两个元素求一次和,得到的所有值和a数组里原来的所有数全部存到b数组里面,现在给你b数组,让你求出对应的a数组并按照从小到大的顺序输出。

分析:

首先把b数组从小到大排序处理,之后,b数组里最小的两个一定是a数组里的数,取出这两个数 b[1]、b[2] 然后删除 a[1]+a[2],再取出 b 中当前最小的,即为 a[3] ,在删除a[1] + a[3]、a[2]+a[3] …… 以此类推,直到取出了 b 中的所有 a 。关于如何删除,我选择用优先队列存储当前已经确定的所有 a 两两组合所能产生的所有 b ,在每一次要取最小值的时候,判断当前b的值是否等于队首,如果等于就删除队首,并且寻找下一个。

代码:

#include<bits/stdc++.h>using namespace std;struct cmp1{    bool operator ()(int &a,int &b){        return a>b;//最小值优先    }};int a[1000];int b[200000];int main(){    int n;    while(scanf("%d",&n)!=EOF)    {        for(int i=0;i<n;i++)        {            scanf("%d",&b[i]);        }        if(n==0)        {            printf("0\n");            continue;        }        if(n==1)        {            printf("1\n%d\n",b[0]);            continue;        }        sort(b,b+n);        priority_queue<int,vector<int>,cmp1>q;        a[0]=b[0];        a[1]=b[1];        q.push(a[0]+a[1]);        int num=2;        for(int i=2;i<n;i++)        {            if(q.empty()==1||b[i]!=q.top())            {                a[num]=b[i];                for(int j=0;j<num;j++)                {                    q.push(a[num]+a[j]);                    //cout<<"push"<<a[num]+a[j]<<endl;                }                num++;            }            else            {                //cout<<"pop:"<<b[i]<<endl;;                q.pop();            }        }        printf("%d\n",num);        printf("%d",a[0]);        for(int i=1;i<num;i++)        {            printf(" %d",a[i]);        }        printf("\n");    }}
原创粉丝点击