fork download
  1. #include <iostream>
  2. #include <cstring>
  3. #include <string>
  4.  
  5. using namespace std;
  6.  
  7. typedef long long ll;
  8.  
  9. string N;
  10. ll memo[20][11][11][2][2];
  11.  
  12. ll dp(int pos, int prev1, int prev2, bool tight, bool leading_zero) {
  13. if (pos == N.size()) {
  14. return 1; // We have formed a valid number
  15. }
  16. if (memo[pos][prev1 + 1][prev2 + 1][tight][leading_zero] != -1) {
  17. return memo[pos][prev1 + 1][prev2 + 1][tight][leading_zero];
  18. }
  19. ll res = 0;
  20. int limit = tight ? N[pos] - '0' : 9;
  21. for (int d = 0; d <= limit; ++d) {
  22. bool new_tight = tight && (d == limit);
  23. bool new_leading_zero = leading_zero && (d == 0);
  24. int new_prev1 = prev1, new_prev2 = prev2;
  25. if (new_leading_zero) {
  26. // Leading zeros, prev1 and prev2 remain -1
  27. res += dp(pos + 1, -1, -1, new_tight, true);
  28. } else {
  29. // Check for palindromic substrings
  30. if (prev1 == d) continue; // Palindrome of length 2
  31. if (prev2 == d) continue; // Palindrome of length 3
  32. new_prev2 = prev1;
  33. new_prev1 = d;
  34. res += dp(pos + 1, new_prev1, new_prev2, new_tight, false);
  35. }
  36. }
  37. return memo[pos][prev1 + 1][prev2 + 1][tight][leading_zero] = res;
  38. }
  39.  
  40. ll count(string num) {
  41. N = num;
  42. memset(memo, -1, sizeof(memo));
  43. return dp(0, -1, -1, true, true);
  44. }
  45.  
  46. int main() {
  47. ll a, b;
  48. cin >> a >> b;
  49. if (a > b) swap(a, b); // Ensure a <= b
  50. ll ans = count(to_string(b)) - (a > 0 ? count(to_string(a - 1)) : 0);
  51. cout << ans << endl;
  52. return 0;
  53. }
  54.  
Success #stdin #stdout 0.01s 5276KB
stdin
11032505 10912606
stdout
31995