华为OD机试 2025A卷题库疯狂收录中,刷题点这里
专栏导读
本专栏收录于《华为OD机试真题(Python/JS/C/C++)》。
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。
一、题目描述
有一个荒岛,只有左右两个港口,只有一座桥连接这两个港口,现在有一群人需要从两个港口逃生,有的人往右逃生,有的往左逃生,如果两个人相遇,则PK,体力值大的能够打赢体力值小的,体力值相同则同归于尽,赢的人才能继续往前逃生,并较少相应地体力。
二、输入描述
一行非0整数,用空格隔开,正数代表向右逃生,负数代表向左逃生。
三、输出描述
最终能够逃生的人数。
四、解题思路
题意是这样的:
体力值大的能够打赢体力值小的,体力值相同则同归于尽,赢的人才能继续往前逃生,并较少相应地体力。
正数代表向右逃生,负数代表向左逃生。
- 那就将正数加到一个集合里,负数加到一个集合里;
- 然后开始遍历取值;
- 体力值大的能够打赢体力值小的,并较少相应地体力;
- 体力值相同则同归于尽;
- 最后输出正数集合和负数集合的大小之和,最终能够逃生的人数;
五、效果展示
1、输入
10 20 -20 -5 10
2、输出
2
3、说明
正数集合:10 20 10
负数集合: -20 -5
- 20和-20同归于尽;
- 10和-5,抵消5体力值;
- 最终能够逃生的人数2人。
六、Python算法源码
def main():
# 读取一行输入,包含非0整数,用空格隔开
nums = list(map(int, input().strip().split()))
# 正数栈
positive_stack = []
# 负数栈
negative_stack = []
for num in nums:
if num > 0:
# 正数直接入栈
positive_stack.append(num)
else:
# 负数代表向左逃生
remain_num = abs(num)
while positive_stack:
positive_top = positive_stack[-1]
if remain_num > positive_top:
# 消除当前的正数,还可以继续碰撞
remain_num -= positive_top
positive_stack.pop()
elif remain_num < positive_top:
# 消除当前的正数,然后修改top值
modify_num = positive_top - remain_num
positive_stack.pop()
positive_stack.append(modify_num)
remain_num = 0
break
else:
# 相等,同归于尽
positive_stack.pop()
remain_num = 0 # 被消除了
break
# 如果还活着,负数入负数栈
if remain_num > 0:
negative_stack.append(-remain_num)
print(len(positive_stack) + len(negative_stack))
if __name__ == "__main__":
main()
七、JavaScript算法源码
function main() {
const input = require('readline-sync');
// 读取一行输入,包含非0整数,用空格隔开
const nums = input.question().trim().split(' ').map(Number);
// 正数栈
const positiveStack = [];
// 负数栈
const negativeStack = [];
nums.forEach(num => {
if (num > 0) {
// 正数直接入栈
positiveStack.push(num);
} else {
// 负数代表向左逃生
let remainNum = Math.abs(num);
while (positiveStack.length > 0) {
const positiveTop = positiveStack[positiveStack.length - 1];
if (remainNum > positiveTop) {
// 消除当前的正数,还可以继续碰撞
remainNum -= positiveTop;
positiveStack.pop();
} else if (remainNum < positiveTop) {
// 消除当前的正数,然后修改top值
const modifyNum = positiveTop - remainNum;
positiveStack.pop();
positiveStack.push(modifyNum);
remainNum = 0;
break;
} else {
// 相等,同归于尽
positiveStack.pop();
remainNum = 0; // 被消除了
break;
}
}
// 如果还活着,负数入负数栈
if (remainNum > 0) {
negativeStack.push(-remainNum);
}
}
});
console.log(positiveStack.length + negativeStack.length);
}
// 运行主函数
main();
八、C算法源码
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_NUMS 1000
void push(int stack[], int *top, int value) {
stack[++(*top)] = value;
}
int pop(int stack[], int *top) {
return stack[(*top)--];
}
int peek(int stack[], int top) {
return stack[top];
}
int is_empty(int top) {
return top == -1;
}
int main() {
char input[10000];
int nums[MAX_NUMS];
int nums_count = 0;
// 读取一行输入
fgets(input, sizeof(input), stdin);
// 使用空格分割输入并转换为整数
char *token = strtok(input, " ");
while (token != NULL) {
nums[nums_count++] = atoi(token);
token = strtok(NULL, " ");
}
int positive_stack[MAX_NUMS];
int negative_stack[MAX_NUMS];
int pos_top = -1;
int neg_top = -1;
for (int i = 0; i < nums_count; i++) {
int num = nums[i];
if (num > 0) {
// 正数直接入栈
push(positive_stack, &pos_top, num);
} else {
// 负数代表向左逃生
int remain_num = abs(num);
while (!is_empty(pos_top)) {
int positive_top = peek(positive_stack, pos_top);
if (remain_num > positive_top) {
// 消除当前的正数,还可以继续碰撞
remain_num -= positive_top;
pop(positive_stack, &pos_top);
} else if (remain_num < positive_top) {
// 消除当前的正数,然后修改top值
int modify_num = positive_top - remain_num;
pop(positive_stack, &pos_top);
push(positive_stack, &pos_top, modify_num);
remain_num = 0;
break;
} else {
// 相等,同归于尽
pop(positive_stack, &pos_top);
remain_num = 0; // 被消除了
break;
}
}
// 如果还活着,负数入负数栈
if (remain_num > 0) {
push(negative_stack, &neg_top, -remain_num);
}
}
}
// 输出剩余的元素数量
printf("%d\n", pos_top + 1 + neg_top + 1);
return 0;
}
九、C++算法源码
#include <iostream>
#include <vector>
#include <stack>
#include <cstdlib>
#include <sstream>
using namespace std;
int main() {
string input;
// 读取一行输入,包含非0整数,用空格隔开
getline(cin, input);
// 使用stringstream来处理输入的分割和转换
stringstream ss(input);
int num;
vector<int> nums;
// 将输入字符串转换为整数数组
while (ss >> num) {
nums.push_back(num);
}
// 正数栈
stack<int> positiveStack;
// 负数栈
stack<int> negativeStack;
for (int num : nums) {
if (num > 0) {
// 正数直接入栈
positiveStack.push(num);
} else {
// 负数代表向左逃生
int remainNum = abs(num);
while (!positiveStack.empty()) {
int positiveTop = positiveStack.top();
if (remainNum > positiveTop) {
// 消除当前的正数,还可以继续碰撞
remainNum -= positiveTop;
positiveStack.pop();
} else if (remainNum < positiveTop) {
// 消除当前的正数,然后修改top值
int modifyNum = positiveTop - remainNum;
positiveStack.pop();
positiveStack.push(modifyNum);
remainNum = 0;
break;
} else {
// 相等,同归于尽
positiveStack.pop();
remainNum = 0; // 被消除了
break;
}
}
// 如果还活着,负数入负数栈
if (remainNum > 0) {
negativeStack.push(-remainNum);
}
}
}
// 输出剩余的元素数量
cout << positiveStack.size() + negativeStack.size() << endl;
return 0;
}
🏆下一篇:华为OD机试真题 - 简易内存池(Python/JS/C/C++ 2025 A卷 200分)
🏆本文收录于,华为OD机试真题(Python/JS/C/C++)
刷的越多,抽中的概率越大,私信哪吒,备注华为OD,加入华为OD刷题交流群,每一题都有详细的答题思路、详细的代码注释、3个测试用例、为什么这道题采用XX算法、XX算法的适用场景,发现新题目,随时更新。