1 条题解

  • 0
    @ 2025-12-15 21:10:21

    #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
    上传者