1. 程式人生 > >CCF NOI1052. Self-Numbers (C++)

CCF NOI1052. Self-Numbers (C++)

1052. Self-Numbers

題目描述

在1949年印度數學家D. R. Daprekar發現了一類稱作Self-Numbers的數。對於每一個正整數n,我們定義d(n)為n加上它每一位數字的和。例如,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。如前13個Self-Number為1, 3, 5, 7, 9, 20, 31, 42, 53, 64, 75, 86, 97。我們將第i個Self-Number表示為a[i],所以a[1]=1, a[2]=3, a[3]=5. . .

輸入

輸入包含整數N、K、s1. . . sk,其中1<=N<=107,1<=K<=5000,以空格和換行分割。

輸出

在第一行你需要輸出一個數,這個數表示在閉區間[1, N]中Self-Number的數量。第二行必須包含以空格劃分的K個數,表示a[s1]. . a[sk],這裡保證所有的a[s1]. . a[sk]都小於N。(例如,如果N=100,sk可以為1-13,但不能為14,因為a[14]=108>100)

樣例輸入

100 10
1 2 3 4 5 6 7 11 12 13

樣例輸出

13
1 3 5 7 9 20 31 75 86 97

資料範圍限制

1<=N<=107,1<=K<=5000

C++程式碼

#include <iostream>
#include <cmath>
#include <cstring>
#include <cassert>

using namespace std;
 
const int MAX_N = 10000000;
const int MAX_K = 5000;
 
int SelfNumbersCount[MAX_N+1];
int SelfNumbers[MAX_N+1];
 
int getdn(int n)
{
    int
dn = n; while(n > 0) { dn += n % 10; n /= 10; } return dn; } int main(void) { int N, K; cin >> N >> K; // assert(N>=1 && N <= MAX_N); // assert(K>=1 && K <= MAX_K); memset(SelfNumbersCount, 0, sizeof(SelfNumbersCount)); int numOfSelfNumbers = 1; for(int n=1; n<=N; n++) { int dn = getdn(n); if(dn <= N) { SelfNumbersCount[dn]++; } if(!SelfNumbersCount[n]) { SelfNumbers[numOfSelfNumbers++] = n; } } cout << numOfSelfNumbers-1 << endl; int sk; for(int k=1; k<=K; k++) { cin >> sk; cout << SelfNumbers[sk] << " "; } cout << endl; return 0; }