• Source
    1. // ideone.com/ysdd6b
    2. #include <iostream>
    3. #include <algorithm>
    4. #include <cmath>
    5. #include <functional>
    6. #include <numeric>
    7. #include <vector>
    8. #include <boost/multiprecision/cpp_int.hpp>
    9.  
    10. using namespace std;
    11.  
    12. using BigInt = boost::multiprecision::int128_t;
    13.  
    14. const int N = 36;
    15. const int W = N * (1 - 1 / log10(16)) + 1;
    16.  
    17. BigInt a[N], d[N], h[N], ax[N][10], smin[N][10], smax[N][10];
    18. int x[N], q, w;
    19. vector<BigInt> X;
    20.  
    21. BigInt toBigInt()
    22. {
    23. return inner_product(x, x + N, d, (BigInt)0);
    24. }
    25.  
    26. void solve(int p = 0, BigInt s = 0, int t = 0)
    27. {
    28. int i, j;
    29. bool isExtraEnd = w == 0 && p == q - 1;
    30.  
    31. if (a[p] >= 0) {
    32. i = lower_bound(smax[p], smax[p] + 10, s) - smax[p];
    33. j = upper_bound(smin[p], smin[p] + 10, s) - smin[p];
    34. } else {
    35. i = lower_bound(smin[p], smin[p] + 10, s, greater<BigInt>()) - smin[p];
    36. j = upper_bound(smax[p], smax[p] + 10, s, greater<BigInt>()) - smax[p];
    37. }
    38.  
    39. for (x[p] = i; x[p] < j; x[p]++) {
    40. if (isExtraEnd && (t + x[p]) % 3) continue;
    41. if (p == N - 1) {
    42. X.push_back(toBigInt());
    43. } else {
    44. solve(p + 1, s - ax[p][x[p]], t + x[p]);
    45. }
    46. }
    47. }
    48.  
    49. int main(void)
    50. {
    51. int i, j;
    52.  
    53. for (i = N - 1; i >= 0; i--) {
    54. d[i] = i + 1 < N ? 10 * d[i + 1] : (BigInt)1;
    55. h[i] = i + 1 < N ? 16 * h[i + 1] : (BigInt)1;
    56. }
    57.  
    58. for (w = 0; w <= W; w++) {
    59. for (i = 0; i < N; i++) a[i] = (i + w < N ? h[i + w] : 0) - d[i];
    60. for (i = 0; i < N; i++) for (j = 0; j < 10; j++) ax[i][j] = a[i] * j;
    61.  
    62. for (i = N - 1; i >= 0; i--) {
    63. for (j = 0; j < 10; j++) {
    64. if (a[i + 1] >= 0) {
    65. smin[i][j] = (i + 1 < N ? smin[i + 1][0] : 0) + ax[i][j];
    66. smax[i][j] = (i + 1 < N ? smax[i + 1][9] : 0) + ax[i][j];
    67. } else {
    68. smin[i][j] = (i + 1 < N ? smin[i + 1][9] : 0) + ax[i][j];
    69. smax[i][j] = (i + 1 < N ? smax[i + 1][0] : 0) + ax[i][j];
    70. }
    71. }
    72. }
    73.  
    74. for (q = 0; q < N; q++) {
    75. if (q > 0) {
    76. a[q - 1] = -d[q - 1];
    77. for (j = 0; j < 10; j++) ax[q - 1][j] = a[q - 1] * j;
    78.  
    79. for (i = q - 1; i >= 0; i--) {
    80. for (j = 0; j < 10; j++) {
    81. if (a[i + 1] >= 0) {
    82. smin[i][j] = smin[i + 1][0] + ax[i][j];
    83. smax[i][j] = smax[i + 1][9] + ax[i][j];
    84. } else {
    85. smin[i][j] = smin[i + 1][9] + ax[i][j];
    86. smax[i][j] = smax[i + 1][0] + ax[i][j];
    87. }
    88. }
    89. }
    90. }
    91. solve();
    92. }
    93. }
    94.  
    95. sort(X.begin(), X.end());
    96. X.erase(unique(X.begin(), X.end()), X.end());
    97.  
    98. for (auto x : X) cout << x << endl;
    99. cout << endl << X.size() << endl;
    100.  
    101. return 0;
    102. }