intdp(int n){ // 本题这句话加不加无所谓 if (n == 0) return0; vector<int> nums; while (n) nums.push_back(n % B), n /= B; // 从最高位向下 int res = 0, last = 0; for (int i = nums.size() - 1; i >= 0; i--) { int x = nums[i]; if (x > 1) { // 没有右子树, 直接计算出结果 res += C[i+1][K-last]; break; } elseif (x > 0) { // 选 0 是左子树 res += C[i][K-last]; // 选 1 是右子树, 当前无法计算结果 last++; if (last > K) break; // 不存在右子树 } // 如果 last > K 代表它下面就不存在任何方案了, 早在之前就 break 了 // 如果 last < K 代表原数中 1 的个数不足 K 个, 这不是合法方案 // 如果 last = K 代表原数中 1 的个数恰为 K 个, n 这个数本身并没有被统计过, 这里加上它 if (i == 0 && last == K) res++; } return res; }
voidinit(){ for (int j = 0; j <= 9; j++) f[1][j] = 1; for (int i = 2; i < N; i++) for (int j = 0; j <= 9; j++) for (int k = 0; k <= 9; k++) if (abs(k-j) >= 2) f[i][j] += f[i-1][k]; }
intdp(int n){ // 本函数不认为 0 是一个合法的数字 if (n == 0) return0; cnt = 0; while (n) nums[cnt++] = n % 10, n /= 10; int res = 0, last = -2; for (int i = cnt-1; i >= 0; i--) { int x = nums[i]; // 如果是最高位从 1 开始枚举, 避免前导零 for (int j = (cnt-1 == i); j < x; j++) if (abs(j-last) >= 2) res += f[i+1][j]; // 如果 x 不满足不代表着比当前要小的数不满 // 因此判断右子树的存在性应当放在循环后面 if (abs(x - last) < 2) break; last = x; // 加上 n 这个数本身 if (i == 0) res++; } // 处理最高位不是 1 的情况 for (int i = 1; i < cnt; i++) for (int j = 1; j <= 9; j++) res += f[i][j]; return res; }
voidinit(){ for (int j = 0; j <= 9; j++) f[j][1] = 1; for (int n = 2; n < N; n++) for (int j = 0; j <= 9; j++) for (int k = j; k <= 9; k++) f[j][n] += f[k][n-1]; }
intdp(int n){ if (n == 0) return1; cnt = 0; while (n) nums[cnt++] = n % 10, n /= 10; int res = 0, last = 0; for (int i = cnt-1; i >= 0; i--) { int x = nums[i]; if (x < last) break; for (int j = last; j < x; j++) res += f[j][i+1]; last = x; if (!i) res++; } return res; }
intmain(){ init(); int l, r; while (~scanf("%d%d", &l, &r)) printf("%d\n", dp(r) - dp(l-1)); return0; }
constint N = 15, M = 100; int f[N][N][M], p; int nums[N], cnt;
voidinit(){ for (int j = 0; j <= 9; j++) f[1][j][j % p]++; for (int i = 2; i < N; i++) for (int m = 0; m < p; m++) for (int j = 0; j <= 9; j++) for (int k = 0; k <= 9; k++) f[i][j][m] += f[i-1][k][((m-j)%p+p)%p]; }
intdp(int n){ if (n == 0) return1; cnt = 0; while (n) nums[cnt++] = n % 10, n /= 10; int res = 0, last = 0; for (int i = cnt-1; i >= 0; i--) { int x = nums[i]; for (int j = 0; j < x; j++) res += f[i+1][j][((-last)%p+p)%p]; // last 代表前缀数位之和 last += x; if (i == 0 && last % p == 0) res++; } return res; }
voidinit(){ for (int j = 0; j <= 9; j++) f[1][j] = 1; f[1][4] = 0; for (int i = 2; i < N; i++) for (int j = 0; j <= 9; j++) for (int k = 0; k <= 9; k++) { if (j == 4 || k == 4) continue; if (j == 6 && k == 2) continue; f[i][j] += f[i-1][k]; } }
intdp(int n){ if (n == 0) return1; cnt = 0; while (n) nums[cnt++] = n % 10, n /= 10; int res = 0, last = 0; for (int i = cnt-1; i >= 0; i--) { int x = nums[i]; for (int j = 0; j < x; j++) { if (last == 6 && j == 2) continue; if (j == 4) continue; res += f[i+1][j]; } if (x == 4) break; if (last == 6 && x == 2) break; if (i == 0) res++; last = x; } return res; }
intmain(){ init(); int l, r; while (scanf("%d%d", &l, &r), l || r) { printf("%d\n", dp(r) - dp(l-1)); } return0; }
voidinit(){ for (int j = 0; j <= 9; j++) { f[1][j][j] = 1; } for (int k = 0; k <= 9; k++) { for (int i = 2; i < N; i++) { for (int j = 0; j <= 9; j++) { for (int u = 0; u <= 9; u++) { f[i][j][k] += f[i-1][u][k]; } // 当前位后面可以 j000~j999 一共 pow10(i-1) 种选择 if (j == k) f[i][j][k] += pow(10, i-1); } } } }
intdp(int n, int k){ // 这个 dp 函数本身不包括前导 0,因此单个的 0 是永远不会被算上的, 比如 dp(10, 0) 返回 1 // 所以不用特殊处理 if (n == 0) return0; idx = 0; while (n) nums[idx++] = n % 10, n /= 10; int res = 0, cnt = 0; for (int i = idx - 1; i >= 0; i--) { int x = nums[i]; // 特判首位 for (int j = (idx - 1 == i); j < x; j++) res += f[i+1][j][k]; if (x == k) { cnt++; int p = 0; for (int z = i-1; z >= 0; z--) p = p * 10 + nums[z]; res += p; } if (i == 0) res += cnt; } // 加上前导零的情况 for (int i = 0; i < idx; i++) for (int j = 1; j <= 9; j++) res += f[i][j][k]; return res; }
intmain(){ init(); int l, r; while (scanf("%d%d", &l, &r), l || r) { if (l > r) swap(l, r); for (int k = 0; k <= 9; k++) printf("%d ", dp(r, k) - dp(l-1, k)); puts(""); } return0; }