1 条题解

  • 0
    @ 2025-11-11 10:20:26

    题目理解

    我们有一个长度为 (K)、首项为 (N)、公差为 1 的等差数列:

    [ N, N+1, N+2, \dots, N+K-1 ]

    对于每个数,我们只知道它的某一位数字(个位、十位、百位等中的某一位),用 (B_i) 表示第 (i) 项的这个数字。
    要求找到最小的 (N),使得存在一种“取某一位”的方式,使得取出的数字序列正好是 (B_0, B_1, \dots, B_{K-1})。


    关键难点

    • 同一个数字 (N+i) 可能有多个位数(个位、十位、百位等),我们只取其中一个位数,并且这个位数可以随 (i) 变化。
    • 不同的 (i) 选取的位数可以不同(比如 (N) 取个位,(N+1) 取十位,等等)。
    • 要找到最小的 (N) 使得存在一种取位方案匹配给定的 (B_i) 序列。

    代码思路分析

    1. 状态表示

    代码中把每个 (B_i) 转换成一个位掩码 1 << x,表示这一项允许的“数字集合”其实只有一个数字 (x)。
    然后递归地尝试确定每一位(从低位到高位)的取值。

    2. 递归函数 solve

    函数参数:

    • vector<int> A:表示当前剩余的需要匹配的数字序列,每个元素是一个位掩码,表示该位置允许的数字集合。
    • ll ld:上一位数字(last digit),用于处理进位对高位的影响。
    • bool ty:类型标记,可能与首位是否为 0 有关。

    3. 递归过程

    • 如果 A.size() == 1,处理最后一个数字的约束,构造满足数字集合的最小数。
    • 否则,枚举当前最低位的可能数字 bg(0 到 9,但有限制条件 Upper),然后根据这个数字和连续数字的递增(考虑进位),更新剩余数字的约束 req,递归求解高位部分。

    4. 构造答案

    递归返回的是高位部分的值,乘以 10 加上当前位 bg,得到当前层的结果。
    最终取所有可能中的最小值。


    算法核心

    这实际上是一个按位确定 + 递归搜索的方法:

    1. 从最低位开始,枚举该位数字。
    2. 根据等差数列递增的性质(+1 可能引起进位),推导出高一位数字的允许集合。
    3. 递归到高位求解,合并结果。
    4. 利用可行性剪枝和取最小值的策略,找到最小 (N)。

    样例分析

    样例:

    K = 6
    B = 7 8 9 5 1 2
    

    输出 47,因为:

    • 47(个位 7)
    • 48(个位 8)
    • 49(个位 9)
    • 50(十位 5)
    • 51(个位 1)
    • 52(个位 2)

    满足 B 序列,且 47 是最小的。


    复杂度

    最坏情况是指数级,但实际由于数字位数有限(最多 10 种数字,且进位链有限),加上剪枝,可以较快求解。


    算法标签

    • 递归搜索
    • 位运算
    • 数学(等差数列)
    • 构造
    • 1

    信息

    ID
    5215
    时间
    1000ms
    内存
    256MiB
    难度
    10
    标签
    递交数
    1
    已通过
    1
    上传者