CCF NOI1052. Self-Numbers
時間限制: 1000 ms 空間限制: 262144 KB 具體限制
題目描述
在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<=10^7,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<=10^7,1<=K<=5000
題記:
這道題有點麻煩……需要先計算在閉區間[1, N]中Self-Number的數量並輸出,在輸出小於N的a[s1]……a[sk]。
C++程式如下:
#include <iostream> #include <cstring> using namespace std; const int N = 10000000; int sncount[N+1]; int sn[N+1]; int self_number(int n) { int sum = n; while(n) { sum += n % 10; n /= 10; } return sum; } int main(void) { int n, k, s, count, i, j; memset(sncount, 0, sizeof(sncount)); cin >> n >> k; //計算在閉區間[1, N]中Self-Number的數量 count = 1; for(i=1; i<=n; i++) { j = self_number(i); if(j <= N) sncount[j]++; if(!sncount[i]) sn[count++] = i; } cout << count - 1 << endl; for(i=1; i<=k; i++) { cin >> s; cout << sn[s] << " "; } return 0; }