1 条题解

  • 0
    @ 2026-5-5 19:16:03

    B. 大数加法 – 详细题解

    问题重述

    给定一个整数 xx10x101810 \le x \le 10^{18}),判断是否存在两个位数相同大整数 AABB,使得 A+B=xA + B = x
    大整数定义为:其每一位数字都在 5599 之间(包含端点)。

    关键观察

    AABB 的位数为 LL。那么它们每一位上的数字 ai,bi[5,9]a_i, b_i \in [5,9],且 AABB 的长度相同。
    两个 LL 位数相加,和可能是一位 LL 位数,也可能是 L+1L+1 位数(当最高位的和加上进位达到 1010 或以上时)。
    因此可能的位数情况有两种:

    1. xx 恰好有 LL 位(即没有额外的进位溢出);
    2. xxL+1L+1 位(最高位只能为 11,因为两个最多 99 的数字相加再加进位最多 1919)。

    所以对于给定的 xx,我们只需检查两种可能的位数:L=len(x)L = \text{len}(x)L=len(x)1L = \text{len}(x)-1(当 len(x)2\text{len}(x) \ge 2 时)。
    如果其中一种情况可行,则答案为 YES,否则为 NO

    数位处理与进位约束

    从低位到高位逐位判断是否存在合法的 ai,bia_i, b_i 以及进位值。
    did_ixx 从低位开始第 ii 位上的数字(i=0i=0 表示个位)。
    设进位数 cic_i 表示第 ii 位相加后产生的进位(ci{0,1}c_i \in \{0,1\}),其中 c0=0c_0 = 0(最低位无进位输入)。
    对于第 ii 位(i=0L1i=0 \dots L-1),我们有:

    [ a_i + b_i + c_i = d_i + 10 \cdot c_{i+1} ]

    其中 ci+1c_{i+1} 表示向高位的进位(0011)。
    已知 ai,bi[5,9]a_i, b_i \in [5,9],因此 ai+bi[10,18]a_i + b_i \in [10, 18]

    等式分析

    给定 cic_idid_i,我们需要判断是否存在 ci+1{0,1}c_{i+1} \in \{0,1\} 以及 ai,bi[5,9]a_i,b_i \in [5,9] 使得上式成立。
    因为 ai+bi=di+10ci+1cia_i + b_i = d_i + 10 c_{i+1} - c_i

    • ci+1=0c_{i+1}=0 时,ai+bi=dicia_i + b_i = d_i - c_i,必须 10\ge 1018\le 18
    • ci+1=1c_{i+1}=1 时,ai+bi=di+10cia_i + b_i = d_i + 10 - c_i,也必须 10\ge 1018\le 18

    同时注意 dicid_i - c_idi+10cid_i+10-c_i 均为正整数(因为 di0d_i \ge 0,且最低位 d0d_0 来自 xx 的个位,可能为 00,但需保证最终和为正整数)。

    更简单的判定方式是:
    对于给定的 cic_idid_i,可能的进位输出 ci+1c_{i+1} 必须满足:

    [ 10 \le d_i + 10c_{i+1} - c_i \le 18 ]

    即差值落在 [10,18][10,18]
    若存在 ci+1{0,1}c_{i+1} \in \{0,1\} 满足该不等式,则这一位可行,并可将 ci+1c_{i+1} 作为下一位置的进位输入。

    因此我们可以从最低位开始,维护当前可能的进位值集合 {0,1}\{0,1\} 中哪些是可行的,然后逐位转移。
    最终处理完所有 LL 位后,需检查最终的进位 cLc_L 是否满足长度要求:

    • 如果 xx 的位数等于 LL(即没有最高进位),则必须有 cL=0c_L = 0
    • 如果 xx 的位数等于 L+1L+1(存在额外进位),则必须有 cL=1c_L = 1,并且此时 xx 的最高位必须为 11(因为两个 LL 位数相加,最高位产生进位 11,且不会超过 11)。

    算法步骤

    对于给定的 xx

    1. 提取其十进制数字串 ss(高位到低位)。
    2. 分别尝试两种长度情况:
      • 情况 AL=sL = |s|,要求最终进位 cL=0c_L = 0
      • 情况 BL=s1L = |s|-1(当 s2|s| \ge 2 时),要求最终进位 cL=1c_L = 1,并且 ss 的最高位必须为 11(因为进位得到的最高位只能是 11)。
    3. 对于每种情况,进行从低位到高位的进位状态模拟
      • 初始进位集合 carry={0}\text{carry} = \{0\}
      • 对于第 ii 位(i=0,,L1i=0,\dots,L-1),取 xx 的对应位数字 did_i(低位对齐,不足的高位补 00 或直接忽略)。
      • 对于当前 carry\text{carry} 中的每个值 cic_i,检查是否可以为 ci+1=0c_{i+1}=011,使得 10di+10ci+1ci1810 \le d_i + 10c_{i+1} - c_i \le 18。将可行的 ci+1c_{i+1} 加入新的集合。
      • 若某一步集合为空,则该情况不可行。
    4. 若任一情况成功,输出 YES,否则 NO

    时间复杂度

    每个测试用例处理 O(s)O(|s|) 位,s18|s| \le 18,且常数极小,可在 11 秒内轻松处理 t104t \le 10^4 个测试用例。

    正确性说明

    该算法本质上是确定性有限自动机 (进位作为状态)的可行性判定。由于每位只有 0011 两种进位输入,且转移规则完全由 did_i 决定,因此通过逐位检查即可确定是否存在满足条件的 A,BA,B

    注意:我们不需要显式求出 A,BA,B,只需存在性。同时,由于 ai,bia_i,b_i 的范围连续且转移条件简单,没有必要枚举具体数值,只需验证进位转移的可能性。

    示例验证

    • x=1337x=1337:位数 44,尝试 L=4L=4。低位到高位模拟可行,最终进位为 00,成功(如 658+679658+679)。
    • x=200x=200:位数 33,尝试 L=3L=3:最低位 d0=0,c0=0d_0=0,c_0=0,只能取 c1=1c_1=1(因为 0+100=100+10-0=10[10,18][10,18])。继续模拟至高位,发现无法满足,再尝试 L=2L=2(即看作 +00+00? 实际 L=2L=2 时,xx 应有 33 位,所以最高位是进位得到的 11,但 200200 的最高位是 22,矛盾),所以无解。
    • x=69x=69:位数 22。尝试 L=2L=2:个位 99c0=0c_0=09+10c1[10,18]9+10c_1 \in [10,18]c1=1c_1=1。十位 66c1=1c_1=1,需 6+10c21[10,18]6+10c_2-1 \in[10,18],若 c2=0c_2=05<105<10;若 c2=1c_2=11515 可行,但最终进位 c2=1c_2=1 要求 L=2L=2 时最高位由进位产生,但 xx 的十位是 66 不是 11,矛盾。所以 NONO

    结论

    本题通过分析进位规律,使用简单的数位 DP(状态数仅为 22)即可高效求解,无需复杂的高精度运算。代码实现时注意字符串的索引转换和边界情况即可。

    • 1

    信息

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