We consider a positive integer perfect, if and only if the sum of its digits is exactly 10. Given a positive integer k, your task is to find the k-th smallest perfect positive integer.
A single line with a positive integer k (1 ≤ k ≤ 10 000).
A single number, denoting the k-th smallest perfect integer.
1
19
2
28
The first perfect integer is 19 and the second one is 28.
题意:
找到第k小的Perfect Number(每一位数的和为10)
可以利用 各位数和为10的数 + 9 和依然为 10
从前往后推出每一位是什么数字
具体步骤:
先判断第k小完美数的位数,然后判断该位数为几,然后还有些细节问题,有点像是二分求第k大的感觉
如第二列的9 表示一个两位数的和为10 的共有9 种
位数为 i(i >= 3) 的完美数的种数 = 位数为i-1 的各位数和为 k 的种数之和(k = 9,8,..,2,1)
因为是完美数所以 i 位数第 i 位不为 0,其余位之和 + 第 i 位 (1~9) = 10 其余位数之和可以为(9~1)
位数为 i(i >= 3)的各位数和为k(10 > k > 0) 的种数 = 位数为 i-1 的各位数和为 j 的种数之和 (k > j >= 0)
因为不是完美数所以 i 位数第 i 位可以为 0,其余位之和 (k~0) + 第 i 位 (0~k) = k
#include <iostream> #include <stdio.h> #include <string.h> using namespace std; int n,m = 10; int a[10][15]; int main() { a[2][10] = 9; for(int i=0;i<=9;i++) a[2][i] = i + 1; for(int i=3;i<=8;i++) { for(int k=9;k>=1;k--){ a[i][10] += a[i-1][k]; } for(int j=9;j>=0;j--){ for(int k=j;k>=0;k--){ a[i][j] += a[i-1][k]; } } } scanf("%d",&n); string ans = ""; for(int i=2;i<=8;i++){ //先找到位数 if(n<=a[i][10]){ //位数剩下两位就要直接来 if(i==2){ ans += ('0' + n); ans += ('0' + 10 - n); break; } for(int k=9;k>=1;k--){ //第一位是9到1,其余位是9到0所以第一位要拿出来考虑 if(a[i-1][k]>=n){ m = k; ans += ('0' + 10 - k); break; } n -= a[i-1][k]; } if(i==3){ for(int k=m;k>=0;k--){ if(a[2][k]>=n){ ans += ('0' + n - 1); ans += ('0' + k - n + 1); break; } } } for(int j=i-2;j>=2;j--){ for(int k=m;k>=0;k--){ if(a[j][k]>=n){ ans += ('0' + m - k); m = k; if(j==2){ ans += ('0' + n - 1); ans += ('0' + k - n + 1); break; } break; } n -= a[j][k]; } } break; } n -= a[i][10]; } cout<<ans<<endl; return 0; }