打卡信奥刷题(1109)用C++实现信奥 P1900 自我数

P1900 自我数

题目背景

#题目有加强

题目描述

在 1949 年印度数学家 D. R. Daprekar 发现了一类称作 Self-Numbers 的数。对于每一个正整数 nnn,我们定义 d(n)d(n)d(n)nnn 加上它每一位数字的和。例如, d(75)=75+7+5=87d(75) = 75 + 7 + 5 = 87d(75)=75+7+5=87。给定任意正整数 nnn 作为一个起点,都能构造出一个无限递增的序列:n,d(n),d(d(n)),d(d(d(n))),…n, d(n), d(d(n)), d(d(d(n))), \ldotsn,d(n),d(d(n)),d(d(d(n))), 例如,如果你从 333333 开始,下一个数是 33+3+3=3933 + 3 + 3 = 3933+3+3=39,再下一个为 39+3+9=5139 + 3 + 9 = 5139+3+9=51,再再下一个为 51+5+1=5751 + 5 + 1 = 5751+5+1=57,因此你所产生的序列就像这样:33,39,51,57,69,84,96,111,114,120,123,129,141,…33, 39, 51, 57, 69, 84, 96, 111, 114, 120, 123, 129, 141, \ldots33,39,51,57,69,84,96,111,114,120,123,129,141,。数字 nnn 被称作 d(n)d(n)d(n) 的发生器。在上面的这个序列中,333333393939 的发生器,393939515151 的发生器,515151575757 的发生器等等。有一些数有超过一个发生器,如 101101101 的发生器可以是 919191100100100。一个没有发生器的数被称作 Self-Number。如前 131313 个 Self-Number 为 1,3,5,7,9,20,31,42,53,64,75,86,971, 3, 5, 7, 9, 20, 31, 42, 53, 64, 75, 86, 971,3,5,7,9,20,31,42,53,64,75,86,97。我们将第 iii 个 Self-Number 表示为 aia_iai,所以 a1=1,a2=3,a3=5,…a_1 = 1, a_2 = 3, a_3 = 5, \ldotsa1=1,a2=3,a3=5,

输入格式

输入包含整数 N,K,s1,…,sKN, K, s_1, \ldots, s_KN,K,s1,,sK,其中 1≤N≤1071 \le N \le {10}^71N1071≤K≤50001 \le K \le 50001K5000,以空格和换行分割。

输出格式

在第一行你需要输出一个数,这个数表示在闭区间 [1,N][1, N][1,N] 中 Self-Number 的数量。第二行必须包含以空格划分的 KKK 个数,表示 as1,…,asKa_{s_1}, \ldots, a_{s_K}as1,,asK,这里保证所有的 as1,…,asKa_{s_1}, \ldots, a_{s_K}as1,,asK 都小于 NNN。(例如,如果 N=100N = 100N=100sks_ksk 可以为 1∼131 \sim 13113,但不能为 141414,因为 a14=108>100a_{14} = 108 > 100a14=108>100

输入输出样例 #1

输入 #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

说明/提示

对于 100%100 \%100% 的数据,1≤N≤1071 \le N \le {10}^71N1071≤K≤50001 \le K \le 50001K5000

C++实现

#include<iostream>
#include<bitset>
using namespace std;
bitset<10000001> flag;
int a[1000000];
int d(int x) {
  int s = 0;
  while (x > 0) {
    s+=x%10;
    x/=10;
  }
  return s;
}
int main() {
  int n, k;
  cin >> n >> k;
  for (int i = 1; i <= n; ++i) {
    int j = d(i) + i;
    if (j <= n)
      flag[j] = true;
  }
  int num = 0;
  for (int i = 1; i <= n; ++i) 
    if (flag[i] == false) {
      num++;
	  a[num] = i;
	}
  cout << num << "\n";
  for (int i = 1; i <= k; i++) {
    int s;
    cin >> s;
    cout << a[s] << " ";
  }
}

在这里插入图片描述

后续

接下来我会不断用C++来实现信奥比赛中的算法题、GESP考级编程题实现、白名单赛事考题实现,记录日常的编程生活、比赛心得,感兴趣的请关注,我后续将继续分享相关内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值