Approach
Breadth-first search
For Count Fancy Numbers in a Range, the implementation explores reachable states in layers, which is the standard shape for unweighted shortest paths and minimum-step transitions.
- Model each valid configuration as a state and each legal move as an edge.
- Seed the queue with the starting state and mark it immediately.
- Expand each state once, recording distance or reachability for unseen neighbours.
Code notes
- 116 lines of C++ from the credited upstream file count-fancy-numbers-in-a-range.cpp.
- The implementation visibly relies on sequence storage, cached states.
- 16 loop blocks detected.
Complexity
Verify that each state and transition is processed only a bounded number of times; that determines the traversal cost.
Check the problem constraints before deciding whether this complexity will pass.
Use this to learn the idea, then write your own version.
123 45class Solution {6public:7 long long countFancy(long long l, long long r) {8 const auto& count = [&](int64_t x) {9 const auto& total = [](int64_t n) { 10 int result = 0;11 for (; n; n /= 10) {12 result += n % 10;13 }14 return result;15 };16 17 const auto& length = [](int64_t n) { 18 int result = 0;19 for (; n; n /= 10) {20 ++result;21 }22 return result;23 };24 25 const auto& check = [](int n) { 26 bool asc = true, desc = true;27 for (; n >= 10; n /= 10) {28 if (!((n / 10) % 10 < n % 10)) {29 asc = false;30 }31 if (!((n / 10) % 10 > n % 10)) {32 desc = false;33 }34 }35 return asc || desc;36 };37 38 const auto& bfs = [](int64_t x) { 39 vector<int64_t> result;40 for (int i = 1; i <= min(static_cast<int64_t>(9), x); ++i) {41 result.emplace_back(i);42 }43 for (const auto& diff : {1, -1}) {44 vector<int64_t> q;45 for (int i = 1; i <= min(static_cast<int64_t>(9), x); ++i) {46 q.emplace_back(i);47 }48 while (!empty(q)) {49 vector<int64_t> new_q;50 for (const auto& u : q) {51 const auto& curr = u % 10;52 for (int d = curr + diff; 0 <= d && d <= 9; d += diff) {53 const auto& v = u * 10 + d;54 if (v <= x) {55 new_q.emplace_back(v);56 result.emplace_back(v);57 }58 }59 }60 q = move(new_q);61 }62 }63 return result;64 };65 66 vector<bool> lookup(length(x) * 9 + 1);67 const auto& dp = [&](int64_t x) { 68 const auto& l = length(x);69 const auto& mx = l * 9;70 vector<vector<int64_t>> dp(2, vector<int64_t>(mx + 1)); 71 dp[1][0] = 1;72 int64_t base = pow(10LL, l - 1);73 for (int i = 0; i < l; ++i) {74 vector<vector<int64_t>> new_dp(2, vector<int64_t>(mx + 1));75 const auto& v = (x / base) % 10;76 base /= 10;77 for (int t = 0; t < 2; ++t) {78 for (int s = 0; s <= mx; ++s) {79 if (dp[t][s] == 0) {80 continue;81 }82 const auto& bound = (t == 1) ? v : 9;83 for (int d = 0; d <= bound; ++d) {84 new_dp[t == 1 && d == v][s + d] += dp[t][s];85 }86 }87 }88 dp = move(new_dp);89 };90 91 int64_t result = 0;92 for (int i = 0; i <= mx; ++i) {93 if (lookup[i]) {94 result += dp[0][i] + dp[1][i];95 }96 }97 return result;98 };99 100 for (int i = 0; i < size(lookup); ++i) {101 lookup[i] = check(i);102 }103 const auto& good = bfs(x);104 int64_t cnt = 0;105 for (const auto& x : good) {106 if (lookup[total(x)]) {107 ++cnt;108 }109 }110 return size(good) + dp(x) - cnt;111 };112 113 return count(r) - count(l - 1);114 }115};116