• HOJ1087


    Self Numbers

    My Tags   (Edit)
      Source : ACM ICPC Mid-Central USA 1998
      Time limit : 5 sec   Memory limit : 32 M

    Submitted : 1443, Accepted : 618

    In 1949 the Indian mathematician D.R. Kaprekar discovered a class of numbers called self-numbers. For any positive integer n, define d(n) to be n plus the sum of the digits of n. (The d stands for digitadition, a term coined by Kaprekar.) For example, d(75) = 75 + 7 + 5 = 87. Given any positive integer n as a starting point, you can construct the infinite increasing sequence of integers n, d(n), d(d(n)), d(d(d(n))), .... For example, if you start with 33, the next number is 33 + 3 + 3 = 39, the next is 39 + 3 + 9 = 51, the next is 51 + 5 + 1 = 57, and so you generate the sequence

    33, 39, 51, 57, 69, 84, 96, 111, 114, 120, 123, 129, 141, ...

    The number n is called a generator of d(n). In the sequence above, 33 is a generator of 39, 39 is a generator of 51, 51 is a generator of 57, and so on. Some numbers have more than one generator: for example, 101 has two generators, 91 and 100. A number with no generators is a self-number. There are thirteen self-numbers less than 100: 1, 3, 5, 7, 9, 20, 31, 42, 53, 64, 75, 86, and 97.

    Write a program to output all positive self-numbers less than or equal 1000000 in increasing order, one per line.

    题目大意为打印小于1000000以内的自私数

    自私数是指可由一个数的各位数字与本身的和组成:例如 2 = 1 + 1;  11 = 1 + 0 + 10; 22 = 2 + 0 + 20;这些都是自私数
     
    一开始仿照埃氏筛法的思想,处理一个数字顺带把由这个数字生成的其他所有数字都处理掉。结果总是TLE,附上代码:
     1  #include<iostream>
     2   using namespace std;
     3   
     4   long MaxSize = 1000000;
     5   
     6   long Dc(long Num){
     7       long D = 0;
     8       D = Num + (Num%10) + (Num/10)%10 + (Num/100)%10 + (Num/1000)%10 + (Num/10000)%10 +(Num/100000)%10;
     9       return D;
    10  }
    11  
    12  int main(){
    13      bool List[MaxSize];
    14      for(long i = 1;i <= MaxSize;i++){
    15          if(!List[i])    printf("%d
    ",i);
    16          long no_self = i;
    17          while(no_self <= MaxSize && !List[no_self]){
    18              no_self = Dc(no_self);
    19              if(no_self <= MaxSize)
    20                  List[no_self] = 1;
    21          }
    22      }
    23      return 0;
    24  }

    问题出在17~21行,这段while循环体实质上并没有让外循环for的指标进行非线性变动,即while循环完全是做无用功。这与埃氏筛有本质不同。但观察到,这段代码只需要给出下一个非Self number的序号即可,因此while循环就可以全部摘去,采用在线处理算法的思想,整个算法的复杂度直接将为O(N),下面为AC代码:

     1 /*This Code is Submitted by mathmiaomiao for Problem 1087 at 2015-08-21 23:21:22*/
     2 #include <iostream>
     3 
     4 using namespace std;
     5 
     6 bool List[1000000];
     7 int main() {
     8   long no_self = 0;
     9   for(long i = 1; i < 1000000; ++i) {
    10     if(!(List[i])) printf("%ld
    ",i);
    11     no_self = i + (i%10) + (i/10)%10 + (i/100)%10 + (i/1000)%10 + (i/10000)%10 +(i/100000)%10;
    12     List[no_self] = 1;
    13   }
    14   printf("1000000
    ");
    15   return 0;
    16 }
    What Greek,do put shit!
  • 相关阅读:
    [原]Linux 命令行浏览器
    Linux 命令行浏览器
    [原]Linux 命令行 发送邮件
    Linux 命令行 发送邮件
    [原]Linux 修改时区
    Linux 修改时区
    [原]Ubuntu 下安装Mongodb
    离线解密RDP凭证密码
    [Win]权限维持
    Nginx反向代理
  • 原文地址:https://www.cnblogs.com/grey-qisen/p/4749336.html
Copyright © 2020-2023  润新知