题目

{% fold 点击显/隐题目 %}

今天轮到pw值日了。值日可是一个体力活。Pw首先擦黑板,pw定睛一看黑板,嘿呀,怎么上边有一堆奇奇怪怪的数字。再一看,原来是今天留的一道数学题。赶巧数学老师进来了,pw急忙上前去请教。

老师说:“这不是AHU新生赛“值日的后续”那题吗?”,老师边讲边翻开课本,“给出一个正整数x,求得x和其各位9数字之和是多少?挺简单的吧?你是不是……”

然而今天题目没那么简单。现在已知一个数字和其各位数字之和为n,请求出有几个数字x,满足题目叙述的要求。如果存在这样的数字,请先输出这样数字的个数,再按照从小到大的顺序依次输出这些数字,否则输出0。

一个数字n(1<=n<=10^9) 用EOF判断读入是否结束
若存在满足题意的数字,先输出数字的个数k。 接下来k行,每行一个数字的值。 若不存在,直接输出0。
21 20
1 15 0
{% endfold %}

题解

对于一个数abcd,有a*1000+b*100+c*10+d 按照计算规则,有 a+b+c+d+a*1000+b*100+c*10+d
而a、b、c、d都是一位数,也即即使是最大的9位数99999999,其计算后也仅仅有999999999+9*9

因此对于每一组数据,直接枚举比他大100和比他小100的数,统计一下即可

代码

{% fold 点击显/隐代码 %}```cpp 值日 https://github.com/OhYee/sourcecode/tree/master/ACM 代码备份
#include
#include
#include
#include
using namespace std;

const int maxn=10005;
vector v;
//int vis[maxn];

int d(int t){
int ans = t;
while(t){
ans += t%10;
t/=10;
}
return ans;
}

void getans(int t){
v.clear();
for(int i=max(0,t-1000);i<=t+1000;++i){
if(d(i)==t)
v.push_back(i);
}
int sz = v.size();
printf("%d\n",sz);
for(int i=0;i<sz;++i)
printf("%d\n",v[i]);
}

int main(){
//freopen("in.txt","r",stdin);
//memset(vis,0,sizeof(vis));
int n;
while(scanf("%d",&n)!=EOF){
getans(n);
}
return 0;
}

{% endfold %}