🎀测试目录导航

一级标题

二级标题

三级标题

四级标题

测试a标签的修改效果
下标
\(H_{2}O\)

上标
\(X^2\)


贴一段代码测试

#include <string>
#include <vector>
#include <cstring> // 用于 memset
#include <algorithm> // 用于 min
#include <stdexcept> // 用于 stoll 的异常处理 (可选)

using namespace std;

class Solution {
public:
    // DP 状态数组:dp[位置][是否受限]
    long long dp[17][2]; 
    string num_str;         // 数字 n 的字符串形式
    string s_suffix;        // 后缀 s
    int limit_digit;        // 数字限制 limit
    int n_len;              // 数字 n 的长度
    int s_len;              // 后缀 s 的长度

    // DFS 函数:计算从 pos 位开始,满足状态约束的强大整数后缀数量
    // is_limit: 当前是否受 n 的数位限制
    long long dfs(int pos, bool is_limit) {
        // 基准情况:所有位数都已处理完毕
        if (pos == n_len) {
            return 1; // 成功构建一个满足条件的数字
        }

        // 记忆化:只有非受限状态才能记忆化
        if (!is_limit && dp[pos][is_limit] != -1) {
            return dp[pos][is_limit];
        }

        long long count = 0;
        // 确定当前位能取的最大数字 (受 n 和全局 limit 双重限制)
        int n_digit = is_limit ? (num_str[pos] - '0') : 9; // n 对应位的数字 或 9
        int upper_bound = min(n_digit, limit_digit);      // 不能超过全局 limit

        // 遍历当前位所有可能的数字 d
        for (int d = 0; d <= upper_bound; ++d) {
            
            // 检查后缀限制:仅当我们在后缀对应的位置时才需要检查
            bool in_suffix_part = (pos >= n_len - s_len);
            if (in_suffix_part) {
                // 计算在 s 中的索引
                int s_index = pos - (n_len - s_len); 
                // 如果当前数字 d 与后缀 s 中对应位置的数字不符
                if (d != (s_suffix[s_index] - '0')) {
                    continue; // 跳过此数字 d
                }
            }

            // 如果数字 d 合法 (满足 limit 和后缀要求),进行递归调用
            
            // 确定下一个状态的 is_limit
            // 只有当前受限(is_limit=true)且选择了上界数字(d == n_digit)时,下一位才继续受限
            bool next_is_limit = is_limit && (d == n_digit); 

            count += dfs(pos + 1, next_is_limit);
        }

        // 如果状态可记忆化,则存储结果
        if (!is_limit) {
            dp[pos][is_limit] = count;
        }

        return count;
    }

    // 计算 [1, n_val] 区间内强大整数的数量
    long long solve(long long n_val) {
        // 处理边界情况,例如 start = 0 或 1 时,start - 1 < 0
        if (n_val < 0) return 0; 
        
        // 将数字 n 转换为字符串形式
        num_str = to_string(n_val); 
        n_len = num_str.length();   // 获取数字 n 的位数

        // 快速剪枝:如果 n 的位数小于后缀 s 的位数,则不可能包含 s 作为后缀
        // 注意:s 可能为空字符串,但题目保证 s 是正整数的字符串表示,所以不为空
        if (n_len < s_len) {
             return 0;
        }
        // 可选的更精确检查:如果 n 的数值小于 s 代表的数值
        // try {
        //     if (stoll(s_suffix) > 0 && n_val < stoll(s_suffix)) return 0;
        // } catch (const std::out_of_range& oor) {
        //     // 如果 s 太长,无法转换为 long long,则 n 几乎不可能小于它
        // }


        // 重置 DP 数组(每次调用 solve 都需要重置,-1 表示未计算)
        memset(dp, -1, sizeof(dp));

        // 调用 DFS 开始计算
        // 初始状态:从第 0 位开始,受 n 的限制 (is_limit = true)
        return dfs(0, true); 
    }

    // 主函数:计算 [start, finish] 区间内的强大整数数量
    long long numberOfPowerfulInt(long long start, long long finish, int limit, string s) {
        // 初始化类成员变量(或作为参数传递)
        s_suffix = s;
        limit_digit = limit;
        s_len = s.length();

        // 计算 solve(finish)
        long long count_finish = solve(finish);
        // 计算 solve(start - 1)
        long long count_start_minus_1 = solve(start - 1);

        // 返回差值
        return count_finish - count_start_minus_1;
    }
};
posted @ 2025-06-26 11:18  AlexLee001  阅读(31)  评论(0)    收藏  举报