校验与校验 | 豆包MarsCode AI刷题

33 阅读3分钟

回顾题目

image.png

分析

这道题目的要求是对于给定长度为 nn 的二进制位串 SS,通过对所有长度为 kk 的子串进行异或运算得到校验和。现在需要找出有多少个与 SS 不同的长度为 nn 的二进制位串能够产生相同的校验和,并将结果对 109+710^9 + 7 取模。

举例分析

  • n=1n = 1k=1k = 1 时,只有一个长度为 1 的二进制位串,不存在与它不同但校验和相同的位串,所以输出为 0。
  • n=2n = 2k=1k = 1 时,如果原始位串是“00”或“11”,那么只有一种可能的不同位串能产生相同校验和,即“11”或“00”;如果原始位串是“01”或“10”,那么也只有一种可能的不同位串能产生相同校验和,即“10”或“01”,所以输出为 1。
  • n=2n = 2k=2k = 2 时,输出为“0”,因为长度为 2 的二进制位串总共只有 4 个:“00”“01”“10”“11”。对于长度为 2 的子串,当 k=2k = 2 时,每个位串只有一个长度为 2 的子串。如果两个位串的校验和相同,那么这两个位串必须完全相同,而题目要求与给定的位串不同,所以没有满足条件的位串,输出为 0。

解决这个问题需要考虑不同长度的二进制位串以及不同长度的子串情况,通过分析异或运算的性质来确定满足条件的不同位串的数量。

def solution(n, k):
    MOD = 10**9 + 7
    if k == n:
        return 0
    if k == 1:
        return (1 << (n - k)) - 1
    result = (1 << (n - k)) - 1
    return result % MOD

if __name__ == '__main__':
    print(solution(1, 1) == 0)
    print(solution(2, 1) == 1)
    print(solution(2, 2) == 0)
    print(solution(11, 1) == 1023)

代码分析

一、整体功能

这段代码定义了一个函数solution,用于计算有多少个与给定长度为n的二进制位串不同但能产生相同校验和的长度为n的二进制位串数量,并将结果对10**9 + 7取模。

二、函数分析

  1. solution函数:

    • MOD = 10**9 + 7:定义了一个常量MOD,用于后续取模运算。

    • if k == n::如果子串长度k等于位串长度n,那么只有一个位串,不存在不同的位串能产生相同校验和,所以直接返回 0。

    • if k == 1::当子串长度为 1 时,对于长度为n的位串,除了自身以外,每一位都有两种可能(0 或 1),所以总共有2**(n - k)种不同的位串。但要排除自身这个位串,所以返回(1 << (n - k)) - 1。这里1 << (n - k)是计算2**(n - k)的位运算方式。

    • result = (1 << (n - k)) - 1:当k既不等于n也不等于 1 时,先按照与k = 1时相同的方式计算结果。

    • return result % MOD:最后将结果对MOD取模并返回。

三、主程序分析

if __name__ == '__main__':部分,对solution函数进行了一些测试用例的调用,并通过比较结果是否与预期一致来验证函数的正确性。

总的来说,这段代码通过条件判断和位运算,高效地计算了满足特定条件的不同二进制位串的数量。