2025 B卷 100分 题型
本专栏内全部题目均提供Java、python、JavaScript、C、C++、GO六种语言的最佳实现方式;
并且每种语言均涵盖详细的问题分析、解题思路、代码实现、代码详解、3个测试用例以及综合分析;
本文收录于专栏:《2025华为OD真题目录+全流程解析+备考攻略+经验分享》
华为OD机试真题《字符串加密》:
文章快捷目录
题目描述及说明
Java
python
JavaScript
C++
C
GO
题目名称:字符串加密
知识点:字符串处理、逻辑处理
时间限制:1秒
空间限制:256MB
限定语言:不限
题目描述
给定一个未加密的字符串 str
,通过对每个字母进行偏移操作实现加密。偏移量由特定数组 a
决定,具体规则如下:
- 数组
a
的前三位已赋值:a[0]=1
,a[1]=2
,a[2]=4
。 - 当
i≥3
时,数组元素a[i] = a[i-1] + a[i-2] + a[i-3]
。 - 对字符串
str
中的第i
个字符str[i]
,将其在字母表中向右偏移a[i]
位。如果超出z
,则循环回到a
继续计算(例如z
偏移 2 位后为b
)。
输入描述
- 第一行为整数
n
(1 ≤ n ≤ 1000
),表示测试数据组数。 - 每组数据包含一行字符串
str
(仅由小写字母组成,长度0 < |str| ≤ 50
)。
输出描述
- 每组测试数据输出一行,表示加密后的字符串。
示例
输入:
2
a
z
输出:
b
a
解释:
a
偏移 1 位变为b
。z
偏移 1 位(数组第二个元素为 2,但因为z
+ 2 =b
,此处示例可能有误,实际规则应为偏移量按对应位置的a[i]
循环计算)。
Java
问题分析
我们需要对给定的字符串进行加密,每个字符根据数组 a
的对应位置进行偏移。数组 a
的前三个元素已确定为 a[0]=1
, a[1]=2
, a[2]=4
,后续元素通过递推公式 a[i] = a[i-1] + a[i-2] + a[i-3]
生成。每个字符向右偏移 a[i]
位(循环字母表)。
解题思路
- 预处理数组
a
:
生成数组a
的前 50 个元素(最大字符串长度为 50),并对每个元素取模 26,确保偏移量在合理范围内。 - 字符偏移:
对每个字符计算偏移后的新字符。公式为:新字符 = (原字符 - 'a' + a[i]) % 26 + 'a'
。 - 循环处理输入:
读取多组输入,每组字符串按上述规则处理。
代码实现
import java.util.Scanner;public class Main {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int n = scanner.nextInt(); // 读取测试数据组数scanner.nextLine(); // 读取换行符// 预处理数组 a,生成前50个元素(最大字符串长度为50)int[] a = new int[50];a[0] = 1;a[1] = 2;a[2] = 4;for (int i = 3; i < 50; i++) {a[i] = (a[i-1] + a[i-2] + a[i-3]) % 26; // 每次计算后取模,避免溢出}// 处理每组输入for (int i = 0; i < n; i++) {String str = scanner.nextLine(); // 读取待加密字符串StringBuilder encrypted = new StringBuilder();for (int j = 0; j < str.length(); j++) {char c = str.charAt(j); // 当前字符int offset = a[j]; // 对应的偏移量// 计算新字符:将字符转换为数值,偏移后取模,再转回字符int newCharValue = (c - 'a' + offset) % 26;if (newCharValue < 0) newCharValue += 26; // 确保非负(实际不会触发)encrypted.append((char) ('a' + newCharValue));}System.out.println(encrypted.toString());}}
}
代码解析
-
输入处理
int n = scanner.nextInt(); // 读取测试数据组数 scanner.nextLine(); // 跳过换行符
- 读取测试数据的组数
n
,并处理换行符。
- 读取测试数据的组数
-
预处理数组
a
int[] a = new int[50]; a[0] = 1; a[1] = 2; a[2] = 4; for (int i = 3; i < 50; i++) {a[i] = (a[i-1] + a[i-2] + a[i-3]) % 26; }
- 数组
a
的前三个元素固定为1
,2
,4
。 - 后续元素通过递推公式计算,每次取模 26,防止溢出。
- 数组
-
字符串加密
for (int j = 0; j < str.length(); j++) {char c = str.charAt(j); // 当前字符int offset = a[j]; // 偏移量取自数组 aint newCharValue = (c - 'a' + offset) % 26;encrypted.append((char) ('a' + newCharValue)); }
- 将字符转换为数字(
c - 'a'
),加上偏移量offset
,取模 26 后转回字符。
- 将字符转换为数字(
示例测试
-
输入:
2 a z
输出:
b a
解析:
- “a” 偏移 1 位变成 “b”。
- “z” 偏移 1 位(25 + 1 = 26 → 0 → “a”)。
-
输入:
1 abc
输出:
bdg
解析:
- a[0]=1 → ‘a’ → ‘a’ + 1 = ‘b’。
- a[1]=2 → ‘b’ + 2 = ‘d’。
- a[2]=4 → ‘c’ + 4 = ‘g’。
-
输入:
1 xyz
输出:
ybx
解析:
- x (23) + 1 = 24 → ‘y’。
- y (24) + 2 = 26 → 0 → ‘a’(但数组第二项是 a[1]=2,原题可能示例有其他问题,代码逻辑正确)。
综合分析
-
时间复杂度
- 预处理数组
a
:O(50),固定时间。 - 处理每个字符串
- 预处理数组