HDU 6168 Numbers 思维

来源:互联网 发布:怎么把源码上传到空间 编辑:程序博客网 时间:2024/06/01 18:57


本题就是告诉你有两个数串 其中第一个数串中的每两个元素ai和aj(i<j)相加得到的元素 放入第二个数串里 但由于两个数串给搞的比较混乱 需要解决从中识别出第一个数串并将其输出出来 


本题其实仔细一想就能发现 这个问题 我们从数串的特点上考虑 

第二个数串是第一个数串组成的 那么如何找出第一个数串呢? 当我们把元素排完序后 发现 最小的两个元素一定是第一个数串的 明显没有其他元素能够构成这两个最小的元素

然后我们把这两个数之和从剩下的数中删掉 因为要排除第二串数

然后对余下的数分析 剩下的最小的一个数 一定是个a串中的数 为什么呢  现在我们把最小的像个a串中的元素组成的数删掉了 剩下的最小的数一定不是a串的

因为a串无法组成这个数 那么把新数拉进来 然后每一个老a数和新a数相加 不断在串中删掉这两个的和 不断重复这个过程

剩下的数就是a串数


考虑如何实现 由于每两元素之和都要在排序后到后面的序列中去找 所以我们不如用一个map 

实现方式如下 O(N*N);

#include<bits/stdc++.h>using namespace std;typedef long long ll;const int maxn = 125255;vector<ll>v;map<ll,ll>m;ll a[maxn];int main(){    int t;    while(~scanf("%d",&t))    {        m.clear(),v.clear();        for(int i=1;i<=t;i++)scanf("%lld",&a[i]);        sort(a+1,a+1+t);        v.push_back(a[1]);        v.push_back(a[2]);        m[a[1]+a[2]]++;        for(int i=3;i<=t;i++){            if(m[a[i]]>0){//将两个数之和消耗掉 此处就相当于把后面的b消耗掉                m[a[i]]--;                continue;            }            else{                v.push_back(a[i]);                for(int j=0;j<v.size()-1;j++){                    ll b = v[j] + a[i];//将两个数的加和标记下来                    m[b]++;                }            }        }        printf("%d\n",v.size());        for(int i=0;i<v.size();i++)i==v.size()-1?printf("%lld\n",v[i]):printf("%lld ",v[i]);    }    return 0;}


原创粉丝点击