最新华为上机考试
真题目录:点击查看目录
华为OD面试真题精选:点击立即查看
华为OD机考双机位C卷 - 任务编排系统
题目描述
任务编排服务负责对任务进行组合调度。参与编排的任务有两种类型,其中一种执行时长为taskA,另一种执行时长为taskB。任务一旦开始执行不能被打断,且任务可连续执行。服务每次可以编排num个任务。请编写一个方法,生成每次编排后的任务所有可能的总执行时长。
输入描述
第1行输入分别为:第1种任务执行时长taskA 第2种任务执行时长taskB 这次要编排的任务个数num 以逗号分隔
输出描述
数组形式返回所有总执行时时长,需要按从小到大排列。
备注 :每种任务的数量都大于本次可以编排的任务数量,
- 0 < taskA
- 0 < taskB
- 0 <= num <= 100000`
示例1
输入
1,2,3输出
[3, 4, 5, 6]解题思路
1. 问题分析
我们需要计算完成N NN个任务总共可能花费的时间。
- 已知条件:
- 任务类型 A 的耗时:T a T_aTa
- 任务类型 B 的耗时:T b T_bTb
- 总任务数量:N NN
- 约束:这N NN个任务中,每一个都可以自由选择是做类型 A 还是类型 B。
2. 核心逻辑
这个问题本质上是一个枚举(遍历)问题。因为总任务数是固定的N NN,如果我们确定了做i ii个 A 类任务,那么剩下的N − i N - iN−i个必然是 B 类任务。
步骤如下:
输入解析:
- 获取三个数值:T a T_aTa,T b T_bTb,N NN。
遍历所有组合:
- 我们可以遍历 A 类任务的数量,设为i ii。
- i ii的取值范围是从0 00到N NN(包括 0 和N NN)。
- i = 0 i = 0i=0表示全做 B 类任务。
- i = N i = Ni=N表示全做 A 类任务。
计算总耗时:
- 对于每一个i ii,计算当前组合的总时间:
TotalTime = ( i × T a ) + ( ( N − i ) × T b ) \text{TotalTime} = (i \times T_a) + ((N - i) \times T_b)TotalTime=(i×Ta)+((N−i)×Tb)
- 对于每一个i ii,计算当前组合的总时间:
去重(Deduplication):
- 为什么要考虑去重?如果T a = T b T_a = T_bTa=Tb,或者在某些特定数值组合下,不同的i ii可能会算出相同的总时间。
- 策略:使用一个“集合(Set)”或者“哈希表(Map)”数据结构来存储计算出的结果。这些数据结构的特性是自动过滤重复的元素,只保留唯一值。
排序(Sorting):
- 题目通常要求输出有序的结果(通常是升序)。
- 将去重后的所有结果提取出来,进行从小到大的排序。
Java
importjava.util.*;publicclassMain{publicstaticvoidmain(String[]args){Scannerscanner=newScanner(System.in);// 读取输入行if(scanner.hasNextLine()){Stringline=scanner.nextLine();// 分割字符串String[]parts=line.split(",");// 解析数值,使用 long 防止总时长溢出longtaskA=Long.parseLong(parts[0]);longtaskB=Long.parseLong(parts[1]);intnum=Integer.parseInt(parts[2]);// 使用 TreeSet 自动排序并去重Set<Long>results=newTreeSet<>();// 遍历 taskA 可能出现的次数 (0 到 num)for(inti=0;i<=num;i++){longcountA=i;longcountB=num-i;longtotalTime=countA*taskA+countB*taskB;results.add(totalTime);}// 输出结果,TreeSet 的 toString 方法刚好符合 [a, b, c] 的格式System.out.println(results);}scanner.close();}}Python
importsysdefmain():# 从标准输入读取数据# strip() 用于去除首尾可能的空白字符input_str=input()ifnotinput_str:returntry:# 解析输入: taskA, taskB, numparts=input_str.split(',')task_a=int(parts[0])task_b=int(parts[1])num=int(parts[2])# 使用集合 set 来自动去重results=set()# 遍历 task_a 的数量 i,从 0 到 num# task_b 的数量自然为 num - iforiinrange(num+1):total_time=i*task_a+(num-i)*task_b results.add(total_time)# 转换为列表并排序sorted_results=sorted(list(results))# Python 的列表打印格式默认即为 [a, b, c],符合题目要求print(sorted_results)exceptValueError:# 防止输入格式错误的异常处理passif__name__=="__main__":main()JavaScript
constreadline=require('readline');constrl=readline.createInterface({input:process.stdin,output:process.stdout});rl.on('line',(line)=>{line=line.trim();if(!line)return;constparts=line.split(',');if(parts.length!==3)return;consttaskA=parseInt(parts[0]);consttaskB=parseInt(parts[1]);constnum=parseInt(parts[2]);constresults=newSet();for(leti=0;i<=num;i++){consttotalTime=i*taskA+(num-i)*taskB;results.add(totalTime);}constoutputArray=Array.from(results);// 必须传入比较函数进行升序排列outputArray.sort((a,b)=>a-b);// 【修正点】手动格式化输出// join(', ') 会用逗号加空格连接数组元素// 然后手动加上首尾的方括号console.log(`[${outputArray.join(', ')}]`);rl.close();});C++
#include<iostream>#include<string>#include<sstream>#include<vector>#include<set>#include<algorithm>using namespace std;intmain(){string line;getline(cin,line);istringstreamiss(line);vector<int>parts;string part;while(getline(iss,part,',')){parts.push_back(stoi(part));}if(parts.size()!=3)return0;inttaskA=parts[0];inttaskB=parts[1];intnum=parts[2];set<int>results;for(inti=0;i<=num;i++){inttotalTime=i*taskA+(num-i)*taskB;results.insert(totalTime);}vector<int>outputArray(results.begin(),results.end());// 必须传入比较函数进行升序排列sort(outputArray.begin(),outputArray.end());cout<<"[";for(size_ti=0;i<outputArray.size();i++){cout<<outputArray[i];if(i<outputArray.size()-1){cout<<", ";}}cout<<"]"<<endl;return0;}Go
packagemainimport("bufio""fmt""os""sort""strconv""strings")funcmain(){// 1. 读取标准输入reader:=bufio.NewReader(os.Stdin)// 读取一行(包含换行符)line,err:=reader.ReadString('\n')iferr!=nil{// 如果是空输入或 EOF,直接返回return}// 2. 数据清洗与解析line=strings.TrimSpace(line)ifline==""{return}parts:=strings.Split(line,",")iflen(parts)!=3{return}// 转换字符串为整数// 注意:在 64 位系统下 int 等同于 int64,足够应对大数// 如果担心 32 位系统溢出,可以使用 strconv.ParseInt 转为 int64taskA,_:=strconv.Atoi(parts[0])taskB,_:=strconv.Atoi(parts[1])num,_:=strconv.Atoi(parts[2])// 3. 计算所有可能的结果并去重 (使用 map 模拟 Set)uniqueResults:=make(map[int]bool)fori:=0;i<=num;i++{// 公式:i 个 A,(num-i) 个 BtotalTime:=i*taskA+(num-i)*taskB uniqueResults[totalTime]=true}// 4. 将 map 的 key 提取到切片中varoutput[]intfork:=rangeuniqueResults{output=append(output,k)}// 5. 排序 (Go 的 sort.Ints 默认就是升序)sort.Ints(output)// 6. 格式化输出// Go 默认 fmt.Println(output) 输出为 [3 4 5 6] (无逗号)// 下面代码将其转换为 [3, 4, 5, 6]varstrOutput[]stringfor_,v:=rangeoutput{strOutput=append(strOutput,strconv.Itoa(v))}fmt.Printf("[%s]\n",strings.Join(strOutput,", "))}C语言
#include<stdio.h>#include<stdlib.h>#include<string.h>#defineMAX_LINE1000#defineMAX_RESULTS10000// 比较函数,用于qsortintcompare(constvoid*a,constvoid*b){return(*(int*)a-*(int*)b);}intmain(){charline[MAX_LINE];intresults[MAX_RESULTS];intresultsCount=0;// 读取输入if(fgets(line,sizeof(line),stdin)==NULL){return1;}// 去除行尾的换行符line[strcspn(line,"\n")]=0;// 分割输入char*token=strtok(line,",");inttaskA=atoi(token);token=strtok(NULL,",");inttaskB=atoi(token);token=strtok(NULL,",");intnum=atoi(token);// 计算结果for(inti=0;i<=num;i++){inttotalTime=i*taskA+(num-i)*taskB;// 检查是否已存在该结果intexists=0;for(intj=0;j<resultsCount;j++){if(results[j]==totalTime){exists=1;break;}}// 如果不存在,则添加到结果数组if(!exists){results[resultsCount++]=totalTime;}}// 排序结果qsort(results,resultsCount,sizeof(int),compare);// 输出结果printf("[");for(inti=0;i<resultsCount;i++){printf("%d",results[i]);if(i<resultsCount-1){printf(", ");}}printf("]\n");return0;}文章目录
- 最新华为上机考试
- 题目描述
- 输入描述
- 输出描述
- 示例1
- 解题思路
- 1. 问题分析
- 2. 核心逻辑
- Java
- Python
- JavaScript
- C++
- Go
- C语言