2017 Multi-University Training Contest

来源:互联网 发布:linux系统启动流程简述 编辑:程序博客网 时间:2024/06/02 04:50

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6168


一个序列a有n个数,然后序列b 是由a[i]+a[j]组成的且i != j.给出序列b,求序列a的元素个数

以及这n个元素是什么。

官方题解:

将b数组排序,取出最小的两项作为a_1,a_2a1,a2,删除a_1,a_2,a_1+a_2a1,a2,a1+a2,再取出最小项作为a_3a3,再删除a_3,a_1+a_3,a_2+a_3a3,a1+a3,a2+a3,再取出最小项作为a_4a4,依次列推。


使用使用map暴力求解。


AC代码:

#include <bits/stdc++.h>using namespace std;const int maxn = 1e4;typedef long long ll;ll a[maxn];int main(){    ll num, m;    while(~scanf("%lld", &m))    {        map <ll, ll> M;        ll min1=1000000009,min2=1000000000;        ll n=(sqrt(8*m+1)-1)/2;        for(ll i=0; i<m; i++)        {            scanf("%lld",&num);            if(num < min2)            {                min1=min2;                min2=num;            }            else if(num < min1)            {                min1=num;            }            M[num]++;        }        M[min1]--;        M[min2]--;        a[0] = min2;        a[1] = min1;        ll cnt = 1;        while(cnt != n - 1)        {            for(ll i = 0; i < cnt; ++ i)            {                M[a[i] + a[cnt]] --;            }            map<ll, ll>::iterator it = M.begin();            while(it!= M.end())            {                if(it->second == ll(0))                {                    M.erase(it++);                }                else                {                    break;                }            }            a[++cnt] = M.begin()->first;            M[a[cnt]]--;        }        printf("%lld\n",n);        printf("%lld",a[0]);        for(int i=1; i<n; i++)            printf("% lld",a[i]);        printf("\n");    }    return 0;}