华为OD机试 - 字符串加密(Python/JS/C/C++ 2025 B卷 100分)

在这里插入图片描述

华为OD机试 2025B卷题库疯狂收录中,刷题点这里

专栏导读

本专栏收录于《华为OD机试真题(Python/JS/C/C++)》

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。

一、题目描述

给你一串未加密的字符串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、输入

2
a
z

2、输出

b
a

3、说明

‘a’ +1 -> ‘b’
‘z’ +2 -> ‘b’ (但是因为偏移量为2, ‘z’ +2 = ‘b’)

五、解题思路

题目很简单,多读几遍,其义自见。

我的做题思路是:

  1. 先找出最长的字符串,初始化偏移量集合numList,比如[1,2,4,7,13];
  2. 遍历每一个输入的字符串,获取每一个字符,按照题目规则,进行偏移即可;
  3. 核心算法:若z+1则结果为a;

六、Python算法源码

def get_shift_list(max_length):
    """
    初始化偏移量列表,并对每个偏移量取模26
    :param max_length: 最大字符串长度
    :return: 偏移量列表
    """
    shift_list = [1 % 26, 2 % 26, 4 % 26]
    for i in range(3, max_length):
        next_shift = (shift_list[i-1] + shift_list[i-2] + shift_list[i-3]) % 26
        shift_list.append(next_shift)
    return shift_list

def encrypt_string(s, shift_list):
    """
    对字符串进行加密
    :param s: 原始字符串
    :param shift_list: 偏移量列表
    :return: 加密后的字符串
    """
    encrypted = []
    for i, char in enumerate(s):
        shift = shift_list[i]
        shifted = (ord(char) - ord('a') + shift) % 26 + ord('a')
        encrypted.append(chr(shifted))
    return ''.join(encrypted)

def main():
    n = int(input())
    strings = []
    max_length = 0
    for _ in range(n):
        s = input().strip()
        strings.append(s)
        if len(s) > max_length:
            max_length = len(s)
    
    shift_list = get_shift_list(max_length)
    
    for s in strings:
        print(encrypt_string(s, shift_list))

if __name__ == "__main__":
    main()

七、JavaScript算法源码

function getShiftList(maxLength) {
    /**
     * 初始化偏移量列表,并对每个偏移量取模26
     * @param {number} maxLength - 最大字符串长度
     * @returns {number[]} 偏移量列表
     */
    let shiftList = [1 % 26, 2 % 26, 4 % 26];
    for (let i = 3; i < maxLength; i++) {
        let nextShift = (shiftList[i - 1] + shiftList[i - 2] + shiftList[i - 3]) % 26;
        shiftList.push(nextShift);
    }
    return shiftList;
}

function encryptString(s, shiftList) {
    /**
     * 对字符串进行加密
     * @param {string} s - 原始字符串
     * @param {number[]} shiftList - 偏移量列表
     * @returns {string} 加密后的字符串
     */
    let encrypted = '';
    for (let i = 0; i < s.length; i++) {
        let shift = shiftList[i];
        let shifted = ((s.charCodeAt(i) - 97 + shift) % 26) + 97;
        encrypted += String.fromCharCode(shifted);
    }
    return encrypted;
}

function main() {
    const readline = require('readline');
    const rl = readline.createInterface({
        input: process.stdin,
        output: process.stdout
    });
    
    let input = [];
    rl.on('line', (line) => {
        input.push(line.trim());
    });
    
    rl.on('close', () => {
        let n = parseInt(input[0]);
        let strings = input.slice(1, n +1);
        let maxLength = 0;
        for (let s of strings) {
            if (s.length > maxLength) {
                maxLength = s.length;
            }
        }
        let shiftList = getShiftList(maxLength);
        for (let s of strings) {
            console.log(encryptString(s, shiftList));
        }
    });
}

main();

八、C算法源码

#include <stdio.h>
#include <string.h>

#define MAX_LEN 50
#define MAX_TEST 1000

void get_shift_list(int max_length, int shift_list[]) {
    /**
     * 初始化偏移量列表,并对每个偏移量取模26
     * @param max_length: 最大字符串长度
     * @param shift_list: 偏移量数组
     */
    shift_list[0] = 1 % 26;
    shift_list[1] = 2 % 26;
    shift_list[2] = 4 % 26;
    for(int i=3;i<max_length;i++) {
        shift_list[i] = (shift_list[i-1] + shift_list[i-2] + shift_list[i-3]) %26;
    }
}

int main(){
    int n;
    scanf("%d", &n);
    char strings[MAX_TEST][MAX_LEN +1];
    int max_length =0;
    for(int i=0;i<n;i++){
        scanf("%s", strings[i]);
        int len = strlen(strings[i]);
        if(len > max_length){
            max_length = len;
        }
    }
    int shift_list[MAX_LEN];
    get_shift_list(max_length, shift_list);
    for(int i=0;i<n;i++){
        char encrypted[MAX_LEN +1];
        int len = strlen(strings[i]);
        for(int j=0; j<len; j++){
            int shift = shift_list[j];
            int shifted = ((strings[i][j] - 'a' + shift) %26) + 'a';
            encrypted[j] = (char)shifted;
        }
        encrypted[len] = '\0';
        printf("%s\n", encrypted);
    }
    return 0;
}

九、C++算法源码

#include <iostream>
#include <vector>
#include <string>
using namespace std;

/**
 * 初始化偏移量列表,并对每个偏移量取模26
 * @param max_length: 最大字符串长度
 * @return 偏移量向量
 */
vector<int> get_shift_list(int max_length){
    vector<int> shift_list;
    shift_list.push_back(1 %26);
    shift_list.push_back(2 %26);
    shift_list.push_back(4 %26);
    for(int i=3;i<max_length;i++){
        int next_shift = (shift_list[i-1] + shift_list[i-2] + shift_list[i-3]) %26;
        shift_list.push_back(next_shift);
    }
    return shift_list;
}

/**
 * 对字符串进行加密
 * @param s: 原始字符串
 * @param shift_list: 偏移量向量
 * @return 加密后的字符串
 */
string encrypt_string(const string &s, const vector<int> &shift_list){
    string encrypted = "";
    for(int i=0;i<s.length();i++){
        int shift = shift_list[i];
        char shifted = ((s[i] - 'a' + shift) %26) + 'a';
        encrypted += shifted;
    }
    return encrypted;
}

int main(){
    int n;
    cin >> n;
    vector<string> strings(n);
    int max_length =0;
    for(int i=0;i<n;i++){
        cin >> strings[i];
        if(strings[i].length() > max_length){
            max_length = strings[i].length();
        }
    }
    vector<int> shift_list = get_shift_list(max_length);
    for(auto &s: strings){
        cout << encrypt_string(s, shift_list) << endl;
    }
    return 0;
}


🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2025 B卷 200分)

🏆本文收录于,华为OD机试真题(Python/JS/C/C++)

刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

哪 吒

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值