华为OD机试B卷字符串加密解析(Python解法,附详细解题思路与满分攻略)

题目描述

给你一串未加密的字符串str,通过对字符串的每一个字母进行改变来实现加密,加密方式是在每一个字母str[i]偏移特定数组元素a[i]的量,数组a前三位已经赋值:a[0]=1,a[1]=2,a[2]=4。

当i>=3时,数组元素a[i]=a[i-1]+a[i-2]+a[i-3]。

例如:原文 abcde 加密后 bdgkr,其中偏移量分别是1,2,4,7,13。

输入描述
第一行为一个整数n(1<=n<=1000),表示有n组测试数据,每组数据包含一行,原文str(只含有小写字母,0<长度<=50)。

输出描述
每组测试数据输出一行,表示字符串的密文。

用例

输入

1
xy

输出 ya
说明 第一个字符x偏移量是1,即为y,第二个字符y偏移量是2,即为a。

字符串加密算法解析:如何通过动态偏移数组实现字符转换加密

1. 核心解题思路

1.1 问题拆解

要实现加密,需解决以下两个核心问题:

  1. 生成偏移数组 a
  2. 根据递推公式计算每个位置的偏移量。
  3. 关键点:处理大数问题(偏移量可能非常大)。
  4. 字符偏移转换
  5. 将每个字符按对应的偏移量转换为新字符。
  6. 关键点:字母循环处理(如 z 偏移 1 后应为 a)。

1.2 关键步骤

步骤1:生成偏移数组 a
  • 初始值
  • a[0] = 1
  • a[1] = 2
  • a[2] = 4
  • 递推公式
  • a[i] = a[i-1] + a[i-2] + a[i-3]
  • 优化:模26运算
  • 由于字母表长度为26,偏移量超过26时实际等效于 a[i] % 26
  • 例如,偏移量27等价于1(27 % 26 = 1),避免数值过大。
  • 步骤2:字符偏移转换
  • 字符位置计算
  • 将字符转换为字母表的索引(a=0, b=1, ..., z=25)。
  • 偏移操作
  • 新位置 = (原位置 + 偏移量) % 26
  • 字符还原
  • 将计算后的索引转换回字符。

  • 2. 代码实现与详细注释

    Python代码

    n = int(input())  # 读取测试用例数量
    for _ in range(n):
        s = input().strip()  # 读取原文
        m = len(s)
        a = []  # 初始化偏移数组
        
        # 填充前三个元素(注意字符串长度可能小于3)
        if m >= 1:
            a.append(1)
        if m >= 2:
            a.append(2)
        if m >= 3:
            a.append(4)
        
        # 生成后续元素(i从3到m-1)
        for i in range(3, m):
            # 计算当前偏移量并取模26
            next_val = (a[i-1] + a[i-2] + a[i-3]) % 26
            a.append(next_val)
        
        # 加密每个字符
        encrypted = []
        for i in range(m):
            # 将字符转换为0-25的索引
            original_pos = ord(s[i]) - ord('a')
            # 计算新位置并取模26
            new_pos = (original_pos + a[i]) % 26
            # 转换回字符
            encrypted_char = chr(new_pos + ord('a'))
            encrypted.append(encrypted_char)
        
        # 输出结果
        print(''.join(encrypted))
    

    代码解析

    2.1 生成偏移数组 a
  • 边界处理:当字符串长度小于3时,仅填充有效的前几个元素。
    if m >= 1: a.append(1)
    if m >= 2: a.append(2)
    if m >= 3: a.append(4)
    
  • 递推优化:每次计算新偏移量时对26取模。
    next_val = (a[i-1] + a[i-2] + a[i-3]) % 26
    
  • 2.2 字符偏移转换
  • ASCII转换
  • ord('a') 返回字母 a 的ASCII码(97)。
  • chr(97) 返回ASCII码对应的字符(a)。
  • 循环处理
    new_pos = (original_pos + a[i]) % 26
    

  • 3. 复杂度分析

  • 时间复杂度:O(n * m)
  • 外层循环处理 n 组测试数据。
  • 内层生成偏移数组和字符转换的时间复杂度为 O(m)。
  • 空间复杂度:O(m)
  • 存储偏移数组 a 和加密结果。

  • 4. 优化与扩展

    4.1 预计算偏移数组

  • 若多组测试数据中字符串长度较大,可预先生成长度固定的偏移数组缓存,避免重复计算。
  • 4.2 大数处理的数学依据

  • 由于 a[i] 的偏移量对26取模,递推公式可简化为:
    a[i] = (a[i-1] + a[i-2] + a[i-3]) % 26
    
  • 该优化使得即使 i 很大时,计算也不会溢出。
  • 4.3 扩展功能

  • 解密算法:逆向操作,将偏移量取反(即 new_pos = (original_pos - a[i]) % 26)。

  • 5. 测试与验证

    测试用例1

  • 输入
    1
    xy
    
  • 输出ya
  • 解释
  • x → 索引23 → 23 + 1 = 24 → y
  • y → 索引24 → 24 + 2 = 26 → 26 % 26 = 0 → a
  • 测试用例2

  • 输入
    2
    abcde
    zzz
    
  • 输出
    bdgkr
    cba
    
  • 解释
  • a 偏移1 → b
  • b 偏移2 → d
  • c 偏移4 → g
  • d 偏移7 → k3 + 7 = 10 → 'k'
  • e 偏移13 → r4 + 13 = 17 → 'r'
  • zzz 偏移量为 1,2,4 → 依次变为 c, b, a

  • 6. 总结

    通过动态规划生成偏移数组,并结合模运算处理字符循环,本方法能够高效解决字符串加密问题。代码实现中,通过逐层分解问题、边界条件处理和数学优化,确保了算法的正确性和性能。此思路还可扩展至其他需要周期性偏移的场景(如凯撒密码变种)。

    作者:蜗牛的旷野

    物联沃分享整理
    物联沃-IOTWORD物联网 » 华为OD机试B卷字符串加密解析(Python解法,附详细解题思路与满分攻略)

    发表回复