1 条题解
-
0
#include #include #include using namespace std;
int dp[10][12][2]; // dp[pos][pre][limit] int digits[10]; // 存储数字的每一位
// pos: 当前处理到的位置(从0开始,最高位) // pre: 前一位数字(0~9,初始设为10表示没有前一位) // limit: 当前是否受到上界限制 int dfs(int pos, int pre, bool limit) { // 如果已经处理完所有位,说明找到了一个合法数字 if (pos == -1) { return 1; }
// 如果已经计算过且不受限制,直接返回记忆化结果 if (!limit && dp[pos][pre][limit] != -1) { return dp[pos][pre][limit]; } int upper = limit ? digits[pos] : 9; // 当前位的上限 int count = 0; for (int i = 0; i <= upper; i++) { // 跳过数字4 if (i == 4) { continue; } // 如果前一位是6且当前位是2,跳过 if (pre == 6 && i == 2) { continue; } // 递归到下一位,pre更新为i,limit更新为limit && (i == upper) count += dfs(pos - 1, i, limit && (i == upper)); } // 记忆化(只存储不受限制的情况) if (!limit) { dp[pos][pre][limit] = count; } return count;}
// 计算0到x之间的合法数字个数 int solve(int x) { if (x < 0) return 0;
int len = 0; while (x) { digits[len++] = x % 10; x /= 10; } // 如果x==0,digits数组为空,需要特殊处理 if (len == 0) { digits[len++] = 0; } // 初始化dp数组为-1 memset(dp, -1, sizeof(dp)); // 从最高位开始,pre初始设为10(表示没有前一位) return dfs(len - 1, 10, true);}
int main() { int n, m;
while (cin >> n >> m) { if (n == 0 && m == 0) { break; } // 计算[m, n]区间内的合法数字个数 // 即solve(m) - solve(n-1) int ans = solve(m) - solve(n - 1); cout << ans << endl; } return 0;}
- 1
信息
- ID
- 14558
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 10
- 标签
- (无)
- 递交数
- 2
- 已通过
- 2
- 上传者