7.22华为OD机试真题 新系统 - 统计能源使用时段 (Java/Py/C/C++/Js/Go)
统计能源使用时段2026 华为OD机试真题 7月22日华为OD上机新系统考试真题 100 分题型点击查看华为 OD 机试真题完整目录2026最新华为OD机试新系统卷 双机位C卷 真题题库目录全覆盖题库 逐点算法考点详解题目描述某智慧园区管理系统记录了 N 个连续的能源使用时段每个时段使用的能源类型用整数表示1太阳能2风能3电能4天然气5地热能。为了优化能源配置管理员需要分析在这 N 个时段中连续使用不超过 2 种能源的最长时段长度是多少请编写程序计算这个最大长度。输入描述输入是一个整数数组表示各时段的能源类型数组元素1太阳能2风能3电能4天然气5地热能约束条件1⩽ 数组长度 ⩽100000能源类型为 1-5 的整数输出描述输出最长连续时段的长度。补充说明如果输入为空则输出 0示例1输入1,2,1,2,3,2,2,2输出5说明最长满足条件的连续时段是[2 3 2 2 2]下标 3 到 7长度 5该时段只使用了 2 种能源2 和 3示例2输入1,2,3,4,5输出2说明最长的满足条件的连续时段是 2因为每个时段都不一样。解题思路核心思想题目要求在数组中找到一个最长连续区间使区间内最多只出现 2 种能源类型。这是典型的滑动窗口问题。用左右指针维护一个窗口并用计数表记录窗口内每种能源出现的次数。当窗口内能源类型数量超过 2 时不断右移左指针并减少对应计数直到窗口重新满足“最多 2 种能源”。每次窗口合法时用窗口长度更新答案。算法步骤如果输入数组为空直接输出0。初始化左指针left 0计数表count答案ans 0。右指针从左到右遍历数组将当前能源加入窗口。如果窗口内不同能源类型超过 2则移动左指针并同步减少左侧能源的计数。当某种能源计数变为 0 时将它从计数表中删除。此时窗口合法用right - left 1更新最大长度。复杂度分析设数组长度为n。每个元素最多被右指针加入一次、被左指针移出一次时间复杂度为O(n)。计数表最多保存 3 种能源的临时状态空间复杂度为O(1)。Javaimportjava.util.ArrayList;importjava.util.HashMap;importjava.util.List;importjava.util.Map;importjava.util.Scanner;publicclassMain{staticintsolve(int[]nums){// 空输入没有任何能源时段最长长度为 0if(nums.length0){return0;}// 使用滑动窗口维护最多包含 2 种能源的连续区间MapInteger,IntegercountnewHashMap();intleft0;intbest0;for(intright0;rightnums.length;right){count.put(nums[right],count.getOrDefault(nums[right],0)1);// 能源类型超过 2 种时移动左边界直到窗口重新合法while(count.size()2){intleftValuenums[left];count.put(leftValue,count.get(leftValue)-1);if(count.get(leftValue)0){count.remove(leftValue);}left;}// 当前窗口合法更新最长连续时段bestMath.max(best,right-left1);}returnbest;}publicstaticvoidmain(String[]args){ScannerscannernewScanner(System.in);Stringinputscanner.hasNextLine()?scanner.nextLine().trim():;ListIntegervaluesnewArrayList();if(!input.isEmpty()){String[]partsinput.split(,);for(Stringpart:parts){Stringitempart.trim();if(!item.isEmpty()){values.add(Integer.parseInt(item));}}}int[]numsnewint[values.size()];for(inti0;ivalues.size();i){nums[i]values.get(i);}System.out.println(solve(nums));}}Pythonfromcollectionsimportdefaultdictdefsolve(nums):# 空输入没有可统计的连续时段ifnotnums:return0# 滑动窗口中维护每种能源类型的出现次数left0countdefaultdict(int)best0forright,valueinenumerate(nums):count[value]1# 当窗口内能源类型超过 2 种时持续收缩左边界whilelen(count)2:left_valuenums[left]count[left_value]-1ifcount[left_value]0:delcount[left_value]left1# 窗口合法时更新最大长度bestmax(best,right-left1)returnbesttry:lineinput().strip()exceptEOFError:linenums[]iflineelselist(map(int,line.split(,)))print(solve(nums))JavaScriptconstreadlinerequire(readline);functionsolve(nums){// 空数组表示没有能源使用时段if(nums.length0){return0;}// 使用滑动窗口统计当前连续区间中的能源类型constcountnewMap();letleft0;letbest0;for(letright0;rightnums.length;right){count.set(nums[right],(count.get(nums[right])||0)1);// 超过 2 种能源时收缩窗口左端while(count.size2){constleftValuenums[left];count.set(leftValue,count.get(leftValue)-1);if(count.get(leftValue)0){count.delete(leftValue);}left;}// 当前窗口满足条件记录最大长度bestMath.max(best,right-left1);}returnbest;}constrlreadline.createInterface({input:process.stdin,output:process.stdout,terminal:false});constlines[];rl.on(line,(line)lines.push(line));rl.on(close,(){constinputlines.length0?lines[0].trim():;constnumsinput?[]:input.split(,).map((item)Number(item.trim()));console.log(solve(nums));});C#includealgorithm#includeiostream#includemap#includesstream#includestring#includevectorusingnamespacestd;intsolve(constvectorintnums){// 空输入直接返回 0if(nums.empty()){return0;}// 计数表保存当前窗口中每种能源的出现次数mapint,intcount;intleft0;intbest0;for(intright0;rightstatic_castint(nums.size());right){count[nums[right]];// 若窗口内超过 2 种能源则移动左边界while(count.size()2){intleftValuenums[left];count[leftValue]--;if(count[leftValue]0){count.erase(leftValue);}left;}// 当前窗口合法更新答案bestmax(best,right-left1);}returnbest;}intmain(){string input;getline(cin,input);vectorintnums;stringstreamss(input);string item;while(getline(ss,item,,)){if(!item.empty()){nums.push_back(stoi(item));}}coutsolve(nums)endl;return0;}Gopackagemainimport(bufiofmtosstrconvstrings)funcsolve(nums[]int)int{// 空输入没有任何连续时段iflen(nums)0{return0}// 用滑动窗口维护当前区间内各能源类型的数量count:make(map[int]int)left:0best:0forright,value:rangenums{count[value]// 能源类型超过 2 种时移动左边界直到重新合法forlen(count)2{leftValue:nums[left]count[leftValue]--ifcount[leftValue]0{delete(count,leftValue)}left}// 记录当前合法窗口的最大长度ifright-left1best{bestright-left1}}returnbest}funcmain(){scanner:bufio.NewScanner(os.Stdin)input:ifscanner.Scan(){inputstrings.TrimSpace(scanner.Text())}nums:make([]int,0)ifinput!{for_,part:rangestrings.Split(input,,){value,_:strconv.Atoi(strings.TrimSpace(part))numsappend(nums,value)}}fmt.Println(solve(nums))}C语言#includectype.h#includestdio.h#includestdlib.h#includestring.hintsolve(intnums[],intn){// 空输入时最长连续时段为 0if(n0){return0;}// 能源类型为 1 到 5计数数组记录当前窗口内各类型数量intcount[6]{0};intkind0;intleft0;intbest0;for(intright0;rightn;right){if(count[nums[right]]0){kind;}count[nums[right]];// 窗口内超过 2 种能源时持续右移左边界while(kind2){intleftValuenums[left];count[leftValue]--;if(count[leftValue]0){kind--;}left;}// 当前窗口满足条件更新最大长度intlengthright-left1;if(lengthbest){bestlength;}}returnbest;}intmain(){charinput[500000];if(fgets(input,sizeof(input),stdin)NULL){input[0]\0;}intnums[100005];intn0;char*tokenstrtok(input,,);while(token!NULL){while(isspace((unsignedchar)*token)){token;}if(*token!\0){nums[n]atoi(token);}tokenstrtok(NULL,,);}printf(%d\n,solve(nums,n));return0;}完整用例用例11,2,1,2,3,2,2,2用例21,2,3,4,5用例3用例44,4,4,4用例51,1,2,2,1,2用例61,2,3,2,2,1,1,1,3用例71,2,1,3,4,3,4,4,5,5用例85,1,5,1,5,2,2,2,3用例91,2,3,2,2,2,4,4,4,4,2用例101,1,1,2,3,3,3,2,2,4,4,4,4,5,5,5文章目录统计能源使用时段题目描述输入描述输出描述补充说明示例1示例2解题思路核心思想算法步骤复杂度分析JavaPythonJavaScriptCGoC语言完整用例用例1用例2用例3用例4用例5用例6用例7用例8用例9用例10