Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <cstdio>
- #include <vector>
- using namespace std;
- constexpr int N = 1000000000;
- constexpr int P = 10; // Maximum number of digits in N.
- bool seen[P + 1][13 + 1][2][2][2];
- int dp[P + 1][13 + 1][2][2][2];
- vector<int> d;
- /* Returns the number of unlucky numbers up to N. States are:
- p = Current digit index (0 <= p <= 10)
- sum = Current digit sum (0 <= sum <= 13)
- lesser = True if the current number being constructed is already strictly lesser than N.
- last = True if the last digit of the current number being constructed was a 1.
- has = True if the current number being constructed already has a 13 as a substring. */
- int solve(int p, int sum, bool lesser, bool last, bool has) {
- if (p < 0) {
- return has and sum == 0; // The constructed number is unlucky if it has 13 as a substring and the sum is 13.
- }
- if (seen[p][sum][lesser][last][has]) {
- return dp[p][sum][lesser][last][has];
- }
- seen[p][sum][lesser][last][has] = true;
- dp[p][sum][lesser][last][has] = 0;
- for (int i = 0; i <= min((lesser ? 9 : d[p]), sum); i++) {
- dp[p][sum][lesser][last][has] += solve(p - 1, sum - i, lesser or i < d[p], i == 1, has or (last and i == 3));
- }
- return dp[p][sum][lesser][last][has];
- }
- /* Prints all the unlucky numbers up to N in ascending order. */
- void generate(int cur, int p, int sum, bool lesser, bool last, bool has) {
- if (p < 0) {
- printf("%d\n", cur);
- return;
- }
- for (int i = 0; i <= min((lesser ? 9 : d[p]), sum); i++) {
- // Only traverses to another state if there's a positive amount of unlucky numbers going through that state.
- if (solve(p - 1, sum - i, lesser or i < d[p], i == 1, has or (last and i == 3)) > 0) {
- generate(10 * cur + i, p - 1, sum - i, lesser or i < d[p], i == 1, has or (last and i == 3));
- }
- }
- }
- int main() {
- int n;
- scanf("%d", &n);
- // Extracting the digits of n.
- while (n > 0) {
- d.push_back(n % 10);
- n /= 10;
- }
- // Printing the unlucky numbers up to n in ascending order.
- printf("%d\n", solve(d.size() - 1, 13, false, false, false));
- generate(0, d.size() - 1, 13, false, false, false);
- return 0;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement