什么是华为OD?
华为od是什么意思
“华为OD是Outsourcing Dispacth模式,是华为和外企德科联合招聘的简称。
目前华为大多数是OD招聘。
OD模式也是华为提出的一种新的用工形式,每年都会从OD项目挑优秀员工转为正编。
所有OD和正式员工一样对待,没有差别,部门平时开会、评审等活动都是一起参加的,是“同薪同酬”,都是由华为的HR直接定的薪资,看的是我们技术能力。
附华为OD机考【2024备战秋招】每日一题:2023.07.13-华为OD机试(第一题)-塔子哥的茶杯
题目内容
有一个叫做塔子哥的人,他非常喜欢喝茶。他有 x xx 个奇怪的杯子,每个杯子都可以装入一个正整数。塔子哥决定将这些杯子中的个数字压入一个栈中,但他有些规矩:每次他要向栈中压入一个数字,如果这个数字与栈顶数字相同,他就会将这两个数字取出来相加,并且将它们的和的两倍压入栈中。另外,如果栈顶数字等于前面连续的 y yy 个数字的和(2 22 ≤ \leq≤ y yy ≤ \leq≤ x xx),他也会将这 y yy 个数字取出来相加,并且将它们的和的两倍压入栈中。当然,如果以上两个规则都不满足,他就不会进行任何操作。现在,塔子哥将一组正整数依次压入栈中,请你告诉他最终栈中剩下的数字是什么。
输入描述
使用单个空格隔开的正整数的字符串,如"5 55 6 66 7 77 8 88", 左边的数字先入栈。
正整数的范围为[1 11, 2 31 − 1 2^{31}-12
31
−1]
正整数个数的范围为[1 11,1000 10001000]。
输出描述
最终栈中存留的元素值,元素值使用的单个空格隔开,如"8 88 7 77 6 66 5 55", 从做至右依次为栈顶至栈底的数字。
样例1
输入
55 66 121 5 5
1
输出
10 242
1
解释:向栈压入 121 121121 时,55 5555 + 66 6666 = 121 121121 ,数据合并后入栈 242 242242 ,压入两个 5 55 时,合并为 10 1010 ,最终栈顶至栈底的数字为 10 1010 和 242 242242 .
样例2
输入
7 5 8 9 3
1
输出
3 9 8 5 7
1
解释:无任何整数合并
思路:模拟栈
什么是栈?
栈是一个先进后出的容器,你可以理解为一个只有一边能够打开的羽毛球筒,那我们想把最里面的羽毛球取出来,就得把所有羽毛球都取出来,这就是栈。
我们需要将给出的 n nn 个正整数逐一加入到栈中,但是在每次入栈时,如果我们发现有以下两种情况,就需要做出相应的操作:
当前数 x xx 和栈顶 y yy 是同一个数,那么我们需要取出栈顶数 y yy ,并将一个新的数 x + y x+yx+y 或者说是 2 ∗ x 2*x2∗x 加入到栈中
当前数 x xx 和栈顶开始往下的任意个数(≥ 2 \ge 2≥2)的数的和相等,那么我们需要将所有这些数都取出来,并把一个新的数 2 ∗ x 2*x2∗x 加入到栈中
由于正整数个数 n nn 的范围为[1,1000],因此直接模拟栈实现题目所要求的操作即可。
唯一需要注意的是,在将数字合并之后再次压入栈的同时,可能还会触发数字合并的操作,比如说:
当前栈中有3个数,分别为2,4,3。此时,我们需要将一个数3加入到栈中,我们先是触发了第一个情况,于是我们把3取出,得到了一个新的数 2 ∗ 3 = 6 2*3=62∗3=6 ,并准备将6加入到栈中。这时栈里面有2个数分别为2,4,于是我们又触发了第二个条件,取出2和4,并得到了数字12。
最终,栈里面仅有一个数字,也就是12。
在最坏情况下,在每次压入栈时,都会遍历前面所有数字判断是否有数字(或者一串数字的和)与入栈数字相等(比如一个单调递减的序列),因此该方法的时间复杂度为:O ( N 2 ) O(N^2)O(N
2
)
类似题目推荐
代码
#include <iostream>
#include <cstdio>
using namespace std;
#define ll long long
const int maxn=1e3+10;
ll stack[maxn];
int top;
int main(){
ll x;
while(scanf("%lld",&x)!=EOF){//读入数据
while(1){
// 存在合并后压入栈再次合并的情况,因此循环判断是否有合并的情况
bool flag=false;
ll tmp=0;
for(int i=top;i&⊤--i){// 暴力查找是否和为x的数
tmp+=stack[i];
if(tmp==x){// 存在一段和为x,合并,并更新栈
x=x+tmp;
top=i-1;
flag=true;
break;
}
}
if(flag==false)
break;
}
stack[++top]=x;
}
while(top){
printf("%lld ",stack[top]);
top--;
}
return 0;
}
python
maxn = 1010
stack = [0] * maxn
top = 0
while True:
x = int(input()) # 读入数据
if x == -1:
break
while True:
flag = False
tmp = 0
for i in range(top, 0, -1): # 暴力查找是否和为x的数
tmp += stack[i]
if tmp == x: # 存在一段和为x,合并,并更新栈
x = x + tmp
top = i - 1
flag = True
break
if not flag:
break
top += 1
stack[top] = x
while top:
print(stack[top], end=" ")
top -= 1
Java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
final int maxn = 1010;
long[] stack = new long[maxn];
int top = 0;
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextLong()) {
long x = scanner.nextLong(); // 读入数据
while (true) {
boolean flag = false;
long tmp = 0;
for (int i = top; i > 0; i--) { // 暴力查找是否和为x的数
tmp += stack[i];
if (tmp == x) { // 存在一段和为x,合并,并更新栈
x = x + tmp;
top = i - 1;
flag = true;
break;
}
}
if (!flag) {
break;
}
}
top++;
stack[top] = x;
}
scanner.close();
while (top > 0) {
System.out.print(stack[top] + " ");
top--;
}
}
}
Go
package main
import "fmt"
const maxn = 1010
func main() {
var stack [maxn]int64 // 栈数组
top := 0 // 栈顶指针
var x int64
for {
_, err := fmt.Scanf("%d", &x) // 读入数据
if err != nil {
break
}
for {
flag := false // 标记是否存在合并的情况
var tmp int64 // 临时变量存储和
for i := top; i > 0; i-- { // 暴力查找是否和为x的数
tmp += stack[i]
if tmp == x { // 存在一段和为x,合并,并更新栈
x = x + tmp
top = i - 1
flag = true
break
}
}
if !flag {
break
}
}
top++
stack[top] = x
}
for top > 0 {
fmt.Printf("%d ", stack[top])
top--
}
}
Js
const maxn = 1010; // 最大数组长度
let stack = new Array(maxn); // 栈数组
let top = 0; // 栈顶指针
function main() {
let input = require('readline-sync'); // 导入readline-sync模块,用于读取用户输入
while (true) {
let x = parseInt(input.question()); // 读入数据
if (isNaN(x)) { // 判断输入是否为数字,若不是则退出循环
break;
}
while (true) {
let flag = false; // 标记是否存在合并的情况
let tmp = 0; // 临时变量存储和
for (let i = top; i > 0; i--) { // 暴力查找是否和为x的数
tmp += stack[i];
if (tmp === x) { // 存在一段和为x,合并,并更新栈
x = x + tmp;
top = i - 1;
flag = true;
break;
}
}
if (!flag) {
break;
}
}
top++;
stack[top] = x;
}
while (top > 0) {
process.stdout.write(stack[top] + " "); // 输出栈顶元素并空格分隔
top--;
}
}
main(); // 调用主函数执行