zoukankan      html  css  js  c++  java
  • Self-numbers 2

    翻译:引自 http://www.cnblogs.com/yylogo/archive/2011/06/09/SGU-108.html

    在1949年印度的数学假D.R. Kaprekar发现了一种叫做self-number的经典数字,对于任意正整数n,定义d(n)为n加上n的各个位上的数字(d是数字的意思,Kaprekar发明的一个术语)。如:d(75) = 75 + 7 + 5 = 87。给定任意正整数n,你可以构建出无限的整数递增:n, d(n), d(d(n)), d(d(d(n))), ……举个例子,你从33开始,那么下一个数就是33 + 3 + 3 = 39, 再下一个就是39 + 3 + 9 = 51, 接着就是 51 + 5 + 1 = 57, 那样就生成了一个序列: 33, 39, 51, 57, 69, 84, 96, 111, 114, 120, 123, 129, 141, ... 这里n叫做d(n)母数 上面的数列中,33是39的母数,39是51的母数,51是57的母数,以此类推……有些数字不止一个母数,比如101有两个母数,91和100。没有母数的数字就叫做self-number。让a[i]成为第i个self-number。现在存在13个小于100的self-number: 1, 3, 5, 7, 9, 20, 31, 42, 53, 64, 75, 86, 和 97. (第一个 self-number是a[1]=1, 第二个是 a[2] = 3, :, 第十三个是 a[13]=97);

    输入:

    包含整数 N, K, s1...sk. (1<=N<=107, 1<=K<=5000) 被空格和换行分割开。

    输出:

    第一行你必须输出一个数字——表示在[1,n]中self-numbers的个数。第二行必须输出K个数字:a[s1]..a[sk],用空格分开。保证所有的在a[s1]..a[sk]的self-numbers都在[1,n]的区间内,(比如N = 100, sk 就只能等于1..13并且不能等于14, 以为第14个self-number a[14] = 108, 108 > 100)

     

    分析:因为题目给的空间十分的小,所以不能直接开出那么大的数组来进行判断,需要使用一种节约内存的方法,发现每个数的下一个自环数不会比他本身大太多(因为只是加上了本身的位数和),所以使用优先队列不会占用太多的内存,而且还需要注意的是给的查询可能是无序的,需要先排序.....然后输出的时候再排过来。

     

    代码如下:

    ==========================================================================================================================

    #include<algorithm>
    #include<stdio.h>
    #include<string.h>
    #include<queue>
    using namespace std;
    
    const int MAXN = 5007;
    const int oo = 1e9+7;
    
    struct DATA{
        int e, id;
    }a[MAXN];
    
    struct Node
    {
        int e;
        Node(int e=0):e(e){}
        bool operator <(const Node &t)const
        {
            return e > t.e;
        }
    };
    
    bool cmp1(DATA t1, DATA t2)
    {
        return t1.e < t2.e;
    }
    bool cmp2(DATA t1, DATA t2)
    {
        return t1.id < t2.id;
    }
    
    int main()
    {
        int N, M, cnt=0, Arr[MAXN*2]={0};
        priority_queue<Node> Q;
        Node s(oo);
        Q.push(s);
    
        for(int i=1; i<10000; i++)
            Arr[i] = Arr[i/10] + i%10;
    
        scanf("%d%d", &N, &M);
    
        for(int i=0; i<M; i++)
        {
            scanf("%d", &a[i].e);
            a[i].id = i;
        }
        a[M].e = oo, a[M].id = oo;
        sort(a, a+M, cmp1);
    
        for(int i=1, j=0; i<=N; i++)
        {
            s.e = i+Arr[i%10000]+Arr[i/10000];
    
            Q.push(s);
            s = Q.top();
    
            if(s.e != i)
            {
                cnt++;
                while(cnt == a[j].e)
                    a[j++].e = i;
            }
            while(s.e == i)
            {
                Q.pop();
                s = Q.top();
            }
        }
        
        sort(a, a+M, cmp2);
        printf("%d
    ", cnt);
        for(int i=0; i<M; i++)
            printf("%d%c", a[i].e, i==M?'
    ':' ');
    
        return 0;
    }
  • 相关阅读:
    第 15 章 标签页和工具提示插件
    第 14 章 下拉菜单和滚动监听插件
    第 13 章 模态框插件
    第 12 章 列表组面板和嵌入组件
    第 11 章 进度条媒体对象和 Well 组件
    第 10 章 巨幕页头缩略图和警告框组件
    第 9 章 路径分页标签和徽章组件
    lock()与lockInterruptibly()的区别
    MySQL中Innodb的聚簇索引和非聚簇索引
    MySQL使用可重复读作为默认隔离级别的原因
  • 原文地址:https://www.cnblogs.com/liuxin13/p/4811914.html
Copyright © 2011-2022 走看看