1 条题解

  • 0
    @ 2025-10-24 18:17:31

    最大汉明距离问题详解

    问题分析

    我们需要在区间[l,r][l, r]内找到两个整数aabb(满足labrl \leq a \leq b \leq r),使得它们的十进制表示的汉明距离最大。

    关键观察

    1. 当两个数字位数不同时,较短数字需要补前导零,此时汉明距离等于较长数字的位数
    2. 当两个数字位数相同时,我们需要找到在相同位数情况下差异最大的两个数字

    核心思路

    情况1:位数不同的情况

    如果llrr的位数不同,那么最大汉明距离就是rr的位数。

    证明

    • llnn位,rrmm位,且n<mn < m
    • 我们可以选择a=10m1a = 10^{m-1}(即mm位数的最小值)和b=rb = r
    • 由于aa需要补前导零,实际上比较的是00...0a00...0amm位)和bb
    • 此时汉明距离为mm,这是可能的最大值

    情况2:位数相同的情况

    llrr位数相同时,我们需要寻找在相同前缀之后能够产生最大差异的位置。

    算法策略

    1. 找到llrr从左端开始的第一个不同位置pp
    2. 最大汉明距离等于总位数减去相同前缀的长度

    正确性证明

    • 在位置ppl[p]<r[p]l[p] < r[p]
    • 我们可以选择:
      • aa:在位置ppl[p]l[p],后面所有位取最小值(通常为0)
      • bb:在位置ppr[p]r[p],后面所有位取最大值(通常为9)
    • 这样从位置pp开始的所有位都不同,汉明距离为np+1n - p + 1
    • 这是可能的最大值,因为前p1p-1位必须相同(否则可能超出区间范围)

    算法实现详解

    输入处理

    由于数字可能达到10100000010^{1000000},我们必须使用字符串处理:

    scanf("%s", s + 1);  // 读取l
    scanf("%s", t + 1);  // 读取r
    int n = strlen(s + 1), m = strlen(t + 1);
    

    核心逻辑

    if (n != m)
        printf("%d\n", max(n, m));
    else {
        int p = 0;
        while (p < n && s[p + 1] == t[p + 1])
            p++;
        printf("%d\n", n - p);
    }
    

    代码解析

    • 如果位数不同:直接输出较大位数
    • 如果位数相同:
      • 找到第一个不同的位置pp
      • 汉明距离 = 总位数nn - 相同前缀长度pp

    正确性验证

    样例1验证

    输入:

    l = 11, r = 17
    
    • 位数相同:n=m=2n = m = 2
    • 相同前缀:第一个字符'1'相同,p=1p = 1
    • 汉明距离:21=12 - 1 = 1
    • 验证:选择12121616,二进制表示:
      • 1212 → "12"
      • 1616 → "16"
      • 只有第二位不同,距离为11

    样例2验证

    输入:

    l = 1, r = 11
    
    • 位数不同:n=1n = 1, m=2m = 2
    • 输出:max(1,2)=2\max(1, 2) = 2
    • 验证:选择111010
      • 11 → "01"(补前导零)
      • 1010 → "10"
      • 两位都不同,距离为22

    边界情况分析

    情况1:l=rl = r

    • 位数相同,所有位都相同
    • p=np = n,汉明距离 = nn=0n - n = 0
    • 正确:同一个数字的汉明距离为0

    情况2:llrr相差很大但位数相同

    例如:l=1000l = 1000, r=9999r = 9999

    • 位数相同:n=m=4n = m = 4
    • 第一个不同位置:p=1p = 1('1' vs '9')
    • 汉明距离:41=34 - 1 = 3
    • 可选:a=1000a = 1000, b=9999b = 9999,距离确实为3

    情况3:极端大数

    • 算法使用字符串处理,支持10100000010^{1000000}规模
    • 时间复杂度:O(max(n,m))O(\max(n, m)),线性复杂度

    算法复杂度分析

    时间复杂度

    • 字符串长度比较:O(1)O(1)
    • 相同前缀扫描:O(min(n,m))O(\min(n, m))
    • 总复杂度O(n)O(n),其中nn是数字的位数

    空间复杂度

    • 存储两个字符串:O(n+m)O(n + m)
    • 其他变量:O(1)O(1)
    • 总空间O(n+m)O(n + m)

    数学证明

    定理1:位数不同时的最优性

    llnn位,rrmm位,n<mn < m,则最大汉明距离为mm

    证明

    • 任意两个mm位数的汉明距离最多为mm
    • 选择a=10m1a = 10^{m-1}mm个位:1后面m1m-1个0)和b=rb = r
    • 由于aa需要补前导零,实际上比较的是00...0100...01rr
    • 如果r10m1r \neq 10^{m-1},则所有位都不同,距离为mm
    • 如果r=10m1r = 10^{m-1},则l=rl = r,但此时n=mn = m,矛盾

    定理2:位数相同时的最优性

    llrr都是nn位数,第一个不同位置为pp,则最大汉明距离为np+1n - p + 1

    证明

    • p1p-1位必须相同,否则可能超出[l,r][l, r]范围
    • 在位置pp,我们可以让a[p]=l[p]a[p] = l[p], b[p]=r[p]b[p] = r[p]
    • 对于位置p+1p+1nn
      • aa的这些位取最小值(通常为0)
      • bb的这些位取最大值(通常为9)
    • 这样确保了从位置pp开始的所有位都不同
    • 汉明距离 = (np+1)(n - p + 1)

    扩展思考

    问题变种

    1. 加权汉明距离:不同位可能有不同的权重
    2. 多进制情况:推广到任意进制下的汉明距离
    3. 多个数字:在区间内找kk个数字,最大化两两汉明距离的最小值

    算法优化

    当前的O(n)O(n)算法已经是最优的,因为至少需要扫描输入数据。

    总结

    本题通过巧妙的观察和简单的字符串处理,高效地解决了大数区间内的最大汉明距离问题。核心洞察在于:

    1. 位数差异直接决定最大距离:当位数不同时,答案就是较大数的位数
    2. 前缀匹配确定相同部分:当位数相同时,找到第一个不同位置即可确定最大差异

    算法在O(n)O(n)时间内解决问题,适用于极端大规模的数据输入,体现了在数论问题中字符串处理技术的重要性。

    • 1

    信息

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