华为OD机试 2025A卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。
一、题目描述
向一个空栈中依次存入正整数,假设入栈元素 n(1<=n=2^31-1)按顺序依次为 nx…n4、n3、n2、n1,每当元素入栈时,如果 n1=n2+…+ny(y 的范围[2,x],1<=x<=1000),则 n1~ny 全部元素出栈,重新入栈新元素 m(m=2*n1)。
如: 依次向栈存入 6、1、2、3, 当存入 6、 1、2 时,栈底至栈顶依次为[6、 1、2]; 当存入 3 时 3=2+1,3、2、1 全部出栈,重新入栈元素 6(6=2*3),此时栈中有元素 6;因为 6=6,所以两个 6 全部出栈,存入 12,最终栈中只剩一个元素 12。
二、输入描述
使用单个空格隔开的正整数的字符串,如”5 6 7 8”,左边的数字先入栈,输入的正整数个数为,1<=X<=1000
三、输出描述
最终栈中存留的元素值,元素值使用空格隔开,如”8 7 6 5”,栈顶数字在左边6 1 2 3
1、输入
5 10 20 50 85 1
2、输出
1 170
3、说明
5 + 10 + 20 + 50 = 85
2 * 85入栈,1入栈,输出 1 170
四、测试用例
测试用例1:
1、输入
2 4 8 16
2、输出
16 8 4 2
3、说明
压入2 → 栈:[2]
压入4 → 栈:[4,2]
y=1:4 ≠2
y=2:2+0=2 !=4
压入8 → 栈:[8,4,2]
y=1:8 ≠4
y=2:4 +2=6 !=8
压入16 → 栈:[16,8,4,2]
y=1:16 ≠8
y=2:8 +4=12 !=16
y=3:4 +2 +0=6 !=16
无替换,最终栈:[16,8,4,2],输出为16 8 4 2
测试用例2:
1、输入
3 3 6
2、输出
12
3、说明
压入3 → 栈:[3]
压入3 → 栈:[3,3]
y=1:3 =3 → 替换3为6 → 栈:[6]
压入6 → 栈:[6,6]
y=1:6=6 → 替换6为12 → 栈:[12]
五、解题思路
- 输入若干个数字,空格分割,放入数组arr;
- 遍历arr,取出待入栈元素current;
- 定义已经出栈的元素集合peekList;
- 倒序遍历,栈顶元素先出栈peek;
- 出栈元素依次相加,得到sum;
- 出栈元素之和大于当前待入栈元素,则没必要再比下去了,直接加入当前待入栈元素current;
- 出栈元素之和等于当前待入栈元素,则将已经比较过的栈内元素取出;
- 重新入栈新元素 m(m=2*n1);
- 如果不等,已经出栈的元素集合加入peek;
- 比较不等,则加入待入栈元素;
- 得到最终的list,倒序输出。
六、Python算法源码
from collections import deque
def process_stack(numbers):
stack = deque()
for num in numbers:
stack.appendleft(num) # 压入栈顶
replaced = True
while replaced:
replaced = False
# 遍历可能的y值,从1开始
for y in range(1, len(stack)):
sum_y = sum(list(stack)[:y])
target = stack[y] if y < len(stack) else None
if target is not None and sum_y == target:
# 移除栈顶y个元素和第y+1个元素
for _ in range(y +1):
stack.popleft()
# 压入新的元素2 * target
stack.appendleft(2 * target)
replaced = True
break # 需要重新开始检查
# 构建输出列表,栈顶在左
return list(stack)
if __name__ == "__main__":
input_str = input().strip()
numbers = list(map(int, input_str.split()))
result = process_stack(numbers)
print(' '.join(map(str, result)))
七、JavaScript算法源码
function processStack(input) {
const numbers = input.trim().split(' ').map(Number);
const stack = [];
for (const num of numbers) {
stack.push(num); // 压入栈顶
let replaced = true;
while (replaced) {
replaced = false;
// 遍历可能的y值,从1开始
for (let y = 1; y <= stack.length -1; y++) {
const sum_y = stack.slice(-y).reduce((a, b) => a + b, 0);
const target = stack[stack.length - y -1];
if (target !== undefined && sum_y === target) {
// 移除栈顶y个元素和第y+1个元素
stack.splice(stack.length - y -1, y +1);
// 压入新的元素2 * target
stack.push(2 * target);
replaced = true;
break; // 需要重新开始检查
}
}
}
}
// 构建输出字符串,栈顶在左
return stack.reverse().join(' ');
}
// 示例使用
const input = prompt();
console.log(processStack(input));
八、C算法源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_SIZE 1000
typedef struct {
int data[MAX_SIZE];
int top;
} Stack;
void init(Stack *s) {
s->top = -1;
}
int isEmpty(Stack *s) {
return s->top == -1;
}
void push(Stack *s, int num) {
if (s->top < MAX_SIZE -1) {
s->data[++(s->top)] = num;
}
}
int pop(Stack *s) {
if (!isEmpty(s)) {
return s->data[(s->top)--];
}
return -1; // 表示栈空
}
int main() {
char input[5000];
fgets(input, sizeof(input), stdin);
Stack stack;
init(&stack);
// 分割输入
char *token = strtok(input, " \n");
while (token != NULL) {
int num = atoi(token);
push(&stack, num);
int replaced = 1;
while (replaced) {
replaced = 0;
for (int y =1; y <= stack.top; y++) {
// 计算栈顶y个元素的和
int sum_y =0;
for (int i = stack.top; i > stack.top - y; i--) {
sum_y += stack.data[i];
}
// 获取第(y+1)个元素
if (stack.top - y >=0) {
int target = stack.data[stack.top - y];
if (sum_y == target) {
// 移除栈顶y+1个元素
for (int i =0; i < y +1; i++) {
pop(&stack);
}
// 压入新的元素2 * target
push(&stack, 2 * target);
replaced =1;
break;
}
}
}
}
token = strtok(NULL, " \n");
}
// 输出结果,栈顶在左
for (int i = stack.top; i >=0; i--) {
printf("%d ", stack.data[i]);
}
return 0;
}
九、C++算法源码
#include <bits/stdc++.h>
using namespace std;
int main(){
string input;
getline(cin, input);
vector<int> stack;
// 分割输入
stringstream ss(input);
int num;
while(ss >> num){
stack.push_back(num);
bool replaced = true;
while(replaced){
replaced = false;
// 遍历可能的y值,从1开始
for(int y=1; y <= stack.size()-1; y++){
// 计算栈顶y个元素的和
int sum_y =0;
for(int i=stack.size()-y; i<stack.size(); i++) sum_y += stack[i];
// 获取第(y+1)个元素
if(stack.size() > y){
int target = stack[stack.size()-y-1];
if(sum_y == target){
// 移除栈顶y+1个元素
stack.erase(stack.end()-y-1, stack.end());
// 压入新的元素2 * target
stack.push_back(2 * target);
replaced = true;
break;
}
}
}
}
}
// 输出结果,栈顶在左
for(int i=stack.size()-1; i>=0; i--){
cout << stack[i] << (i ? " " : "\n");
}
}
🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2025 A卷 200分)
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。