1 条题解
-
0
题目理解
我们有一个长度为 (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 可能引起进位),推导出高一位数字的允许集合。
- 递归到高位求解,合并结果。
- 利用可行性剪枝和取最小值的策略,找到最小 (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
- 上传者