洛谷——P2371 EXCEEDED WARNING C(50)
P2371 EXCEEDED WARNING C
題目背景
第三道溢出警告。。。
機(wei)智(suo)的TMXi又搬題來坑大家了。。。
註意時空限制【壞笑】
題目描述
[li]1949年,阿三的數學家D.R. Kaprekar發現了一系列被稱為“塞爾夫數”(self-number)的數。對於任意的正整數n,定義 d(n) 是 n 及其各位數字之和。[/li]
[li]比如說,d(75) = 75 + 7 + 5 = 87. 給出任意的正整數 n 作為起點,你將通過n得到一個無限的遞增序列: d(n), d(d(n)), d(d(d(n))), .... [/li]
[li]再比如說,如果你以33為起點,則下一個數是33 + 3 + 3 = 39,在下一個是39 + 3 + 9 = 51,之後是51 + 5 + 1 = 57.[/li]
[li]由此,你將可以寫出一個數列:33, 39, 51, 57, 69, 84, 96, 111, 114, 120, 123, 129, 141, ... [/li]
[li]n將被稱為d(n)的“啟發者”。(在上面的數列中,33是39的啟發者,39是51的啟發者,以此類推……)[/li]
[li]有的數有多個啟發者,比如101,91和100都是它的啟發者;而有的數沒有啟發者,比如5,它們就是所謂的“塞爾夫數”.[/li]
[li]我們將第i個塞爾夫數記為a[i],有13個塞爾夫數小於100 : 1, 3, 5, 7, 9, 20, 31, 42, 53, 64, 75, 86, 和 97. (a[1]=1, a[2] = 3, ... , a[13]=97);[/li]
輸入輸出格式
輸入格式:
[b]共兩問:[/b]
①輸入整數n (n<10^7),並不換行
②輸入整數k (k<5000),接下來一行k個數,s1, s2, . . . , sk. (n<10^7時,sk<10^6)
n, k中間是空格(雖說這句廢話)
輸出格式:
輸出應為兩行,
第一行是區間[ 1, n ]中塞爾夫數的個數。
第二行k個數,分別對應第i個塞爾夫數,兩個數中間以一個半角空格隔開。
輸入輸出樣例
輸入樣例#1: 復制100 10 1 2 3 4 5 6 7 11 12 13輸出樣例#1: 復制
13 1 3 5 7 9 20 31 75 86 97
說明
空間限制6000KiB
時間限制750ms
篩法:TLE
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define N 10000100 using namespace std; bool not_self[N]; int b,s,n,k,sum,self[N]; int read() { int x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); return x*f; } int work() { for(int i=1;i<=n;i++) { if(!not_self[i]) { self[++sum]=i,b=i; while(b<n) { s=b; while(s) b+=s%10,s/=10; not_self[b]=true; } } } } int main() { n=read();work(); printf("%d\n",sum); k=read(); for(int i=1;i<=k;i++) s=read(),printf("%d ",self[s]); return 0; }50分篩法
洛谷——P2371 EXCEEDED WARNING C(50)