HDU 6168 Numbers 思维

来源:互联网 发布:3b代码编程及图案 编辑:程序博客网 时间:2024/05/22 10:49

题目

      HDU 6168

分析

      官方题解
这里写图片描述
      和HDU 6092很类似,不过区别在于6092那道题目可以取多个不同的数字组成一个新的数,所以要用0-1背包。这道题目只能取两个数字组成一个新的数,所以用一个map维护能够组成的数字就行了,每找到一个新的数字,就遍历之前所有的数来更新map。虽然代码看起来是三重循环,但是复杂度是O(M+N2)

代码

#include <cstring>#include <cstdio>#include <vector>#include <map>using namespace std;const int N = 125255;map<int, int> M1;map<int, int> M2;int b[N], m;int a[N], n;int main(){    //freopen("test.txt", "r", stdin);    //freopen("out.txt", "w", stdout);    while (~scanf("%d", &m))    {        M1.clear();        M2.clear();        for (int i = 1; i <= m; i++)        {            scanf("%d", &b[i]);            M1[b[i]]++;        }        n = 0;        for (map<int, int>::iterator it = M1.begin(); it != M1.end(); it++)        {            int val = it->first;            int cnt1 = it->second;            int cnt2;            if (!M2.count(val)) cnt2 = 0;            else cnt2 = M2[val];            int cnt3 = cnt1 - cnt2;            for (int j = 1; j <= cnt3; j++)            {                a[++n] = val;                for (int k = 1; k < n; k++)                    M2[val + a[k]]++;            }        }        printf("%d\n", n);        for (int i = 1; i <= n; i++)            printf("%d%c", a[i], i < n ? ' ' : '\n');    }    return 0;}