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个塞尔夫数,两个数中间以一个半角空格隔开。
输入输出样例
100 10 1 2 3 4 5 6 7 11 12 13
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; }