当前位置: 首页 > news >正文

华为OD机试新系统真题 【末世分配资源包】

末世分配资源包(Java /C++/Py/Js/Go/C)题解

华为OD机试新系统真题 华为OD上机考试新系统真题 8月12号 200分题型

华为OD机试新系统真题目录点击查看: 华为OD机试新系统真题题库目录|机考题库 + 算法考点详解

题目内容

末世时代,政府为各地分配资源,现有资源分配表nums[n],要求按如下规则分配给k kk个营地:

  1. 每个营地只分配一段连续的分配表
  2. 每个营地至少分到一份资源
  3. 所有的资源必须全部分出
  4. 分配方式:尽量平均分配(即:得利最大的营地获得的资源值尽量小)

输入描述

  1. 资源存储数组nums[n](资源数n nn:0 ≤ n ≤ 1000 0 \le n \le 10000n1000,每份资源数:1 ≤ n u m s [ i ] ≤ 100000 1 \le nums[i] \le 1000001nums[i]100000
  2. 营地数k kk1 ≤ k ≤ min ⁡ ( 50 , n ) 1 \le k \le \min(50, n)1kmin(50,n)

输出描述

在最优平均分配情况下,得利最大团队所获得的资源数

样例1

输入

4,3,6,9,7 2

输出

16

说明
可能的切分:

  • [4],[3,6,8,9,7],最大值:25
  • [4,3],[6,9,7],最大值:22
  • [4,3,6],[9,7],最大值:16
  • [4,3,6,9],[7],最大值:22
    因此,最大值最小的切分方式是第3种,返回16

样例2

输入

3,4,2,1 4

输出

4

说明
可能的切分:

  • [3],[4],[2],[1],最大值:4
    因此,最大值最小的切分方式是第1种,返回4

题解

思路:二分 + 贪心

  1. 这种在...条件下,求最值的基本都是是二分的套路题。见到这种题可以优先考虑二分算法进行处理。

  2. 首先确定上下边界

    • 下边界很容易想到为所有资源的最大值。
    • 上边界为所有资源总和,当k==1的会选择。
  3. 确定好上下边界时,每轮枚举上下边界中间值mid == (left + right) /2, 并判断在每组资源总数不超过mid下分配组数和k的关系,并按照大小关系更新上下边界,直到left == right时结束。更新上下边界规律如下

    • 分配组数 <= k,说明mid值刚好或者值太大,此时可以尝试更新值,更新right = mid
    • 分配组数 > k, 说明mid值太小,必须尝试更达至,更新left = mid + 1
  4. mid限制求解可分配组数采用贪心进行求解,使用sum记录当前组总和,cnt记录已分配组数量,从前往后遍历nums

    1. sum + nums[i] > mid说明该组无法继续容纳当前资源,需要重新分配一个组,更新cnt++, sum = nums[i]
    2. sum + nums[i] <= mid说明该组可以继续容纳当前资源,更新sum += nums[i]

C++

#include<bits/stdc++.h>#include<vector>usingnamespacestd;// 通用 切割函数 函数 将字符串str根据delimiter进行切割vector<int>split(conststring&str,conststring&delimiter){vector<int>result;size_t start=0;size_t end=str.find(delimiter);while(end!=string::npos){result.push_back(stoi(str.substr(start,end-start)));start=end+delimiter.length();end=str.find(delimiter,start);}// 添加最后一个部分result.push_back(stoi(str.substr(start)));returnresult;}intsolve(vector<int>&nums,intk){intn=nums.size();if(n==0){return0;}intleft,right;left=right=0;// 确定二分边界for(inti=0;i<n;i++){// 下边界为最大资源left=max(left,nums[i]);// 上边界为资源总和right+=nums[i];}while(left<right){intmid=(left+right)>>1;// 贪心计算分段数intcount=1;intsum=0;for(inti=0;i<n;i++){if(sum+nums[i]>mid){count++;sum=nums[i];}else{sum+=nums[i];}}// 值刚好或者值太大,尝试更小值if(count<=k){right=mid;// 值太小,应该升高}else{left=mid+1;}}returnleft;}intmain(){string input1;getline(cin,input1);intk;cin>>k;vector<int>nums=split(input1,",");cout<<solve(nums,k);return0;}

JAVA

importjava.io.*;importjava.util.*;publicclassMain{staticintsolve(int[]nums,intk){intn=nums.length;if(n==0){return0;}intleft=0;intright=0;// 确定二分边界for(inti=0;i<n;i++){// 下边界为最大资源left=Math.max(left,nums[i]);// 上边界为资源总和right+=nums[i];}while(left<right){intmid=(left+right)>>1;// 贪心计算分段数intcount=1;intsum=0;for(inti=0;i<n;i++){if(sum+nums[i]>mid){count++;sum=nums[i];}else{sum+=nums[i];}}// 值刚好或者值太大,尝试更小值if(count<=k){right=mid;// 值太小,应该升高}else{left=mid+1;}}returnleft;}publicstaticvoidmain(String[]args)throwsException{BufferedReaderbr=newBufferedReader(newInputStreamReader(System.in));Stringinput1=br.readLine();intk=Integer.parseInt(br.readLine().trim());String[]parts=input1.split(",");int[]nums=newint[parts.length];for(inti=0;i<parts.length;i++){nums[i]=Integer.parseInt(parts[i].trim());}System.out.print(solve(nums,k));}}

Python

defsolve(nums,k):n=len(nums)ifn==0:return0left=0right=0# 确定二分边界foriinrange(n):# 下边界为最大资源left=max(left,nums[i])# 上边界为资源总和right+=nums[i]whileleft<right:mid=(left+right)>>1# 贪心计算分段数count=1sum_val=0foriinrange(n):ifsum_val+nums[i]>mid:count+=1sum_val=nums[i]else:sum_val+=nums[i]# 值刚好或者值太大,尝试更小值ifcount<=k:right=mid# 值太小,应该升高else:left=mid+1returnleft input1=input()k=int(input())nums=list(map(int,input1.split(",")))print(solve(nums,k),end="")

JavaScript

constreadline=require('readline');constrl=readline.createInterface({input:process.stdin,output:process.stdout});letinputs=[];rl.on('line',line=>{inputs.push(line);});rl.on('close',()=>{constinput1=inputs[0];constk=parseInt(inputs[1]);constnums=input1.split(',').map(Number);console.log(solve(nums,k));});functionsolve(nums,k){constn=nums.length;if(n===0){return0;}letleft=0;letright=0;// 确定二分边界for(leti=0;i<n;i++){// 下边界为最大资源left=Math.max(left,nums[i]);// 上边界为资源总和right+=nums[i];}while(left<right){constmid=Math.floor((left+right)/2);// 贪心计算分段数letcount=1;letsum=0;for(leti=0;i<n;i++){if(sum+nums[i]>mid){count++;sum=nums[i];}else{sum+=nums[i];}}// 值刚好或者值太大,尝试更小值if(count<=k){right=mid;// 值太小,应该升高}else{left=mid+1;}}returnleft;}

Go

packagemainimport("bufio""fmt""os""strconv""strings")funcsolve(nums[]int,kint)int{n:=len(nums)ifn==0{return0}left:=0right:=0// 确定二分边界fori:=0;i<n;i++{// 下边界为最大资源ifnums[i]>left{left=nums[i]}// 上边界为资源总和right+=nums[i]}forleft<right{mid:=(left+right)>>1// 贪心计算分段数count:=1sum:=0fori:=0;i<n;i++{ifsum+nums[i]>mid{count++sum=nums[i]}else{sum+=nums[i]}}// 值刚好或者值太大,尝试更小值ifcount<=k{right=mid// 值太小,应该升高}else{left=mid+1}}returnleft}funcmain(){in:=bufio.NewReader(os.Stdin)out:=bufio.NewWriter(os.Stdout)deferout.Flush()input1,_:=in.ReadString('\n')input2,_:=in.ReadString('\n')input1=strings.TrimSpace(input1)input2=strings.TrimSpace(input2)parts:=strings.Split(input1,",")nums:=make([]int,len(parts))fori,s:=rangeparts{nums[i],_=strconv.Atoi(strings.TrimSpace(s))}k,_:=strconv.Atoi(input2)fmt.Fprint(out,solve(nums,k))}

C语言

#include<stdio.h>#include<stdlib.h>#include<string.h>intsolve(int*nums,intn,intk){if(n==0){return0;}intleft=0;intright=0;// 确定二分边界for(inti=0;i<n;i++){// 下边界为最大资源if(nums[i]>left){left=nums[i];}// 上边界为资源总和right+=nums[i];}while(left<right){intmid=(left+right)>>1;// 贪心计算分段数intcount=1;intsum=0;for(inti=0;i<n;i++){if(sum+nums[i]>mid){count++;sum=nums[i];}else{sum+=nums[i];}}// 值刚好或者值太大,尝试更小值if(count<=k){right=mid;// 值太小,应该升高}else{left=mid+1;}}returnleft;}intmain(){charinput1[10000];charinput2[100];fgets(input1,sizeof(input1),stdin);fgets(input2,sizeof(input2),stdin);// 去除换行符input1[strcspn(input1,"\r\n")]='\0';input2[strcspn(input2,"\r\n")]='\0';int*nums=(int*)malloc(sizeof(int)*10000);intn=0;// 使用strtok按逗号切割char*token=strtok(input1,",");while(token!=NULL){nums[n++]=atoi(token);token=strtok(NULL,",");}intk=atoi(input2);printf("%d",solve(nums,n,k));free(nums);return0;}

http://www.cnnetsun.cn/news/3997659.html

相关文章:

  • 网站建设实用教程新手必读:从0到1打造高转化官网的避坑指南与落地策略
  • 如何在VSCode中实现秘密阅读?程序员必备的摸鱼插件完整指南
  • 从零基础到独立建站完整揭秘:一份关于网页制作与网站建设项目教程的深度指南
  • 逻辑分析仪与示波器核心差异解析:从原理到实战的数字系统调试指南
  • 从模糊需求到清晰实现:领域驱动设计与Spring Boot实践
  • AMD Ryzen硬件级调试技术深度解析:SMUDebugTool架构设计与实践应用
  • 为什么三极管,一上PCB板电路就炸?一文带你彻底吃透三极管!
  • CentOS 7系统下MySQL 8.0完整安装与安全配置指南
  • 知识问答大模型(维修)技术方案-文档融合与重排
  • MOOTDX架构设计与性能优化深度解析:构建高性能量化数据接口
  • 告别网盘限速!LinkSwift:九大网盘直链解析的终极解决方案
  • 深度解析北京鑫旺路桥建设有限公司网站:如何成为您靠谱的道路桥梁建设合作伙伴
  • G代码核心命令实战指南:从零掌握CNC加工必备的20%关键指令
  • Python基础入门:从环境搭建到实战项目,系统掌握编程核心
  • 微信聊天记录误删恢复全攻略:从数据存储原理到5种实战方法
  • Android开发必备:adb命令精准控制应用生命周期实战指南
  • ComfyUI-VideoHelperSuite终极指南:从图像序列到专业视频的完整解决方案
  • 米费勒F1采暖保护剂对比测试,6年后依旧有效果
  • 为什么你的上海微信网站建设兼容网站做得像半成品?揭秘前端适配的坑与路
  • Python数据科学入门:Conda与Pip镜像源配置全攻略
  • 国家建设厅网站如何作为权威信息发布平台助力城市更新与民生改善深度解析
  • 揭秘牛商营销型网站建设方案如何帮助企业在流量红利消退后实现业绩逆势增长
  • 从零构建个人AI助手:基于LangChain与DeepSeek的AI Agent实战指南
  • 大一新生如何备赛高教杯成图大赛:从零到国一的实战指南
  • Python爬虫实战:自动化采集App每日热门榜单数据
  • 深入拆解Trae-Agent评估架构:从原理到实战构建AI智能体进化引擎
  • WarcraftHelper终极指南:让经典魔兽争霸III在现代系统重生
  • 贵阳网站建设哪家好方舟企业官网搭建与品牌形象升级全攻略
  • 基于Milvus向量数据库构建用户标签相似度检索系统实战
  • 阴阳师自动化脚本终极指南:3步实现游戏全自动托管