题目:运矿车

小v最近在玩一款挖矿的游戏,该游戏介绍如下:
1、每次可以挖到多个矿石,每个矿石的重量都不一样,挖矿结束后需要通过一款平衡矿车运送下山;
2、平衡矿车有左右2个车厢,中间只有1个车轮沿着导轨滑到山下,且矿车只有在2个车厢重量完全相等且矿石数量相差不超过1个的情况下才能成功运送矿石,否则在转弯时可能出现侧翻。
假设小v挖到了n(n<100)个矿石,每个矿石重量不超过100,为了确保一次性将n个矿石都运送出去,一旦矿车的车厢重量不一样就需要购买配重砝码。请问小v每次最少需要购买多少重量的砝码呢? (假设车厢足够放下这些矿石和砝码,砝码重量任选)

用例:

输入描述:
输入n个正整数表示每个矿石的重量

输出描述:
输出一个正整数表示最少需要购买的砝码重量

输入例子1:
3 7 4 11 8 10

输出例子1:
1

例子说明1:
小v可以将重量3,7和11的矿石放到左车厢,重量4,8和10 放到右车厢,然后购买重量为1的砝码放到左车厢

想法

一开始毫无头绪,想的都是往两个栈里进出,不得要领。
后来想到假设两个车厢都是满的,不做加减,只做交换,就容易了很多。
小车厢的容量是固定的,就是矿石数量一半下取整。只要小车厢的载重逼近半重,大小车厢的载重差就越小,买的砝码就少。可以将数组分成两个大小车厢,通过循环历遍一节车厢的每一块石头,比较另一个车厢中是否有可以替换的矿石,使该车厢载重最逼近标准线(半重)。
但在如何出这个历遍的时候,出现了麻烦。
后来想到用一个标记量记录连续未替换的次数,如果连续一轮都没有替换的,说明已是最优情况,可以跳出导出结果。

    private static int solution(int[] input) {//准备工作---定义小车厢的容量,求小车厢的载重,矿石总重,标准线(半重)int len =input.length/2,littleCaseWeight=0,allweight=0;final double halfweight;for(int i : input){ //求总重allweight+=i;}halfweight=(double)allweight/2;//求半重for(int i=0;i<len;i++){littleCaseWeight+=input[i];}int flag=len;int index=0;while (flag>0){flag--;double deltaweight=Math.abs(halfweight-littleCaseWeight);int swapindex=-1;for(int i=len;i<input.length;i++){int trylittleCaseWeight=littleCaseWeight-input[index]+input[i];if(Math.abs(trylittleCaseWeight-halfweight)<deltaweight){deltaweight=Math.abs(trylittleCaseWeight-halfweight);swapindex=i;}}if(swapindex!=-1){littleCaseWeight=littleCaseWeight-input[index]+input[swapindex];//刷新小车厢载重和交换石块位置int temp=input[index];input[index]=input[swapindex];input[swapindex]=temp;flag=len;//替换后应该再开一轮}index=(index+1)%len;//从头循环}return Math.abs(allweight-2*littleCaseWeight);}

后来又想到两个极端情况。
1.重的矿石先放进小车厢。因为容量固定,在这种情况下还无法超过半重,重石块换轻石块更是不可能,就可以直接导出结果了。
2.轻的石块先放小车厢。因为容量固定,在这种情况下还无法低于半重,轻石块换重石块更是不可能,就可以直接导出结果了。
那先对其进行部分选择排序,判断极端情况,应该能提升不少效率。

    private static int solution(int[] input) {//准备工作---定义小车厢的容量,求小车厢的载重,矿石总重,标准线(半重)int len =input.length/2,littleCaseWeight=0,allweight=0;final double halfweight;for(int i =0;i<len;i++){//进行部分选择排序,把最重的几块矿石填满小车厢int max_index=i;for(int j=i;j<input.length-1;j++){if(input[j]<input[j+1]){max_index=j+1;}}int temp=input[max_index];input[max_index]=input[i];input[i]=temp;}for(int i : input){ //求总重allweight+=i;}halfweight=(double)allweight/2;//求半重for(int i=0;i<len;i++){littleCaseWeight+=input[i];}//准备完后可得,小车厢都是重石块,如果小车载重小于标准线,说明换石块是不可能让形成载重逼近标准线,可直接得到结果if(littleCaseWeight<=halfweight){//            for(int i: input)System.out.print(i+",");return allweight-2*littleCaseWeight;}//如果小车载重高于标准线,就需要调换小石块,使其逼近标准线,应该循环每个石块,在大车厢里找一块轻石块替换该石块,让小车厢载重更逼近标准线。如果1正轮都找不到,说明已经最接近了int flag=len;int index=0;while (flag>0){flag--;double deltaweight=Math.abs(halfweight-littleCaseWeight);int swapindex=-1;for(int i=len;i<input.length;i++){int trylittleCaseWeight=littleCaseWeight-input[index]+input[i];if(Math.abs(trylittleCaseWeight-halfweight)<deltaweight){deltaweight=Math.abs(trylittleCaseWeight-halfweight);swapindex=i;}}if(swapindex!=-1){littleCaseWeight=littleCaseWeight-input[index]+input[swapindex];//刷新小车厢载重和交换石块位置int temp=input[index];input[index]=input[swapindex];input[swapindex]=temp;flag=len;//替换后应该再开一轮}index=(index+1)%len;//从头循环}return Math.abs(allweight-2*littleCaseWeight);}

题目2

今年7月份vivo迎来了新入职的大学生,现在需要为每个新同事分配一个工号。人力资源部同事小v设计了一个方法为每个人进行排序并分配最终的工号,具体规则是:
将N(N<10000)个人排成一排,从第1个人开始报数;如果报数是M的倍数就出列,报到队尾后则回到队头继续报,直到所有人都出列;
最后按照出列顺序为每个人依次分配工号。请你使用自己擅长的编程语言帮助小v实现此方法。

用例:

输入描述:
输入2个正整数,空格分隔,第一个代表人数N,第二个代表M:

输出描述:
输出一个int数组,每个数据表示原来在队列中的位置用空格隔开,表示出列顺序:

输入例子1:
6 3

输出例子1:
3 6 4 2 5 1

例子说明1:
6个人排成一排,原始位置编号即为1-6。最终输出3 6 4 2 5 1表示的是原来编号为3的第一个出列,编号为1的最后一个出列。

想法

看到题目的第一反应是“约瑟夫环问题”,但细细一品又不一样,所以前几天找的数学解法不能套用,那就只能模拟了。但模拟时发现题目隐藏着两个要求
要求1:重新排队(要求新序列)
要求2:还没有分配工号(保留旧信息)
以N=7,M=3为例。结果是3 6 2 7 5 1 4。
要求新序列是指原来的顺序改变了。保留旧信息,例子可见原第三个的人排第一了但还是没有分配工号1号。

最简单就是安排两个全0数组,一个做原队,另一个做新队,定义自增M为号令。原队循环遍历。每次报道%m= =0的人就把自己的index复制到新队,这样内存开销比较大。

    private static String solution(int[] input) {int n=input[0];int m=input[1];int[] res=new int[n];int[] result=new int[n];int index=0;int signednum=1;int M=1;int idx=0;while(idx<n){if(res[index]!=0){index=(index+1)%n;continue;}if(M%m==0){res[index]=1;result[idx]=index+1;idx++;}M++;index=(index+1)%n;}StringBuffer ab=new StringBuffer();for(int i :result){ab.append(i+" ");}return ab.toString();}

另外一种就是单组的推移方法。需要先遍历赋值,每次报道%m==0的人就移到队首,循环的起点也后移。不过这样数组赋值操作很频繁,比较慢。

题目3

小v在公司负责游戏运营,今天收到一款申请新上架的游戏“跳一跳”,为了确保提供给广大玩家朋友们的游戏都是高品质的,按照运营流程小v必须对新游戏进行全方位了解体验和评估。这款游戏的规则如下:
有n个盒子排成了一行,每个盒子上面有一个数字a[i],表示在该盒子上的人最多能向右移动a[i]个盒子(比如当前所在盒子上的数字是3,则表示可以一次向右前进1个盒子,2个盒子或者3个盒子)。
现在小v从左边第一个盒子上开始体验游戏,请问最少需要移动几次能到最后一个盒子上?

用例

输入描述:
输入 :2 2 3 0 4

表示现在有5个盒子,上面的数字分别是2, 2, 3, 0, 4。

输出描述:
输出:2

小v有两种跳法:

跳法1:盒子1 -> 盒子2 -> 盒子3 -> 盒子5,共3下

跳法2:盒子1 -> 盒子3 -> 盒子5,共2下

跳法2的步骤数最少,所以输出最少步数:2。

输入例子1:
2 2 3 0 4

输出例子1:
2

想法

典型的递归求解,只是没说无解时为-1
设数组的解为f()
看这个例子:2 2 3 0 4 和 2 3 0 4, 3 0 4
很容易就得到 f([2 2 3 0 4] )=min( f([2 3 0 4 ] ),f([3 0 4]) )+1
只要将其用编程语言来描述就行了。

另外可以发现,从a往后跳,它的范围是[a的index+1,a的index+a],这样只要在一个循环中分别试探后可达起点数组的次数,取最小值+1返回。如果是空集,就返回默认值(MAX__VALUE。。注意到是比小,如果函数中暂存次数的标记默认结果为-1,当出现一条路不通时,结果就是-1和其他路径次数比较了。所以这里应该设置暂存最小次数的值为极大)

接着分析这个函数需要的参数 :数组 ,次数计数器
数组不用每次都创建新数组,只要添加一个起点参数就可以了。
次数计数器,是每递归一一次,就自增一次的Int;

如果起点就是终点。说明数组已经跳到完结了,返回次数计数器。
,没有到底就看看可达起点的次数,取最小的+1返回。没有可达的点就返回极大值。

这里用的是倒着往前来。

        private static int jump(int endindex ,int[] arr,int deepth ){int minpath=Integer.MAX_VALUE;if(endindex==0){return deepth;}else {for(int i=endindex-1;i>=0;i--){if(arr[i]+i>=endindex){int t=jump(i,arr,deepth+1);minpath=t>minpath?minpath:t;}}return minpath;}}

vivo 2020届校招在线编程笔试相关推荐

  1. vivo 2020届校招在线编程笔试B卷

    1.小v最近在玩一款挖矿的游戏,该游戏介绍如下: 1.每次可以挖到多个矿石,每个矿石的重量都不一样,挖矿结束后需要通过一款平衡矿车运送下山: 2.平衡矿车有左右2个车厢,中间只有1个车轮沿着导轨滑到山 ...

  2. vivo 2020届校招在线编程笔试A卷

    1.小v是公司的运维工程师,现有一个有关应用程序部署的任务如下: 1.一台服务器的磁盘空间.内存是固定的,现在有N个应用程序要部署: 2.每个应用程序所需要的磁盘.内存不同,每个应用程序允许访问的用户 ...

  3. vivo 2020届校招 报数

    1.题目描述: 2.题解: 双端队列 def solution(N, M):# TODO Write your code here# -*- coding:utf-8 -*-# write code ...

  4. vivo 2020届校招 跳盒子,贪心算法

    1.题目描述: 2.题解: 与力扣45题跳跃游戏Ⅱ类似,但要做改动 贪心算法 def solution(step_list):#// TODO Write your code hereend ,max ...

  5. vivo2021届秋季校招在线编程

    vivo2021届秋季校招在线编程 //用队列实现拓扑排序,但因为题目要求"同时可以编译多个文件的情况,按数字升序返回",所以用个小根堆来保持升序的特性. import java. ...

  6. 2020届校招浦发银行 信息科技 创新岗 面经及历年汇总~

    浦发银行 信息科技 创新岗 面经 信息科技岗位又分大数据.系统开发.创新岗(AI) 上海总行,在莲花路1688号面试,因为离得很远,六点就起来坐地铁了,一直看牛客凌晨3点才睡着,一路在地铁上'钓鱼'O ...

  7. 如何看待 2020 届校招算法岗「爆炸」的情况?英雄所见略同

    来自:计算机视觉联盟公众号 转载 :知乎问题 如何看待 2020 届校招算法岗「爆炸」的情况? 链接:https://www.zhihu.com/question/342267611 本文仅作为学术交 ...

  8. 2020届校招总结(秋招+春招)

    2020届校招总结(秋招+春招) 目录 个人情况 秋招 春招 总结 个人情况 末流211本科,通信工程专业,在实验室主要是做机器视觉和深度学习相关,实习在一家500强外企做数据挖掘,主要是在研究时序数 ...

  9. 如何看待 2020 届校招算法岗「爆炸」的情况?

    编辑:忆臻 https://www.zhihu.com/question/342267611 本文仅作为学术分享,如果侵权,会删文处理 如何看待 2020 届校招算法岗「爆炸」的情况? 作者:Ted ...

最新文章

  1. 公司技术部门内部的发展变化过程。
  2. [Json] C#ConvertJson|List转成Json|对象|集合|DataSet|DataTable|DataReader转成Json (转载)...
  3. 【C语言重点难点精讲】C语言指针
  4. js判断file是否为空_JS - 获取文件后缀,判断文件类型(比如是否为图片格式)...
  5. 【自】数据库系统原理(三)——测试总结后,
  6. adb shell 命令详解
  7. 三相同步电机怎么接线图_三相异步电机的正反转原理图解
  8. 饭客网络(基础教程)
  9. 计算机专业bs和cs,BS和CS的区别以及各自的优缺点
  10. java取万位的值,excel表格数值如何取万位整数,来研究下吧
  11. 商品销售订单综合分析
  12. 迅雷磁盘缓存设置过高会影响其它网络应用软件的速度
  13. 本博客通知(亓官劼)
  14. 我们采访了三位学生:他们写代码、95 后、来自大陆和台湾
  15. 宏病毒组(五)|病毒基因组系统发育树
  16. 计算机老师开学第一堂课,开学第一堂课作文(精选8篇)
  17. 计算机3d影视的应用程序,计算机3D技术在电影中的应用
  18. 微信小程序的轮播图宽高
  19. i.MX6ULL驱动开发 | 12 - 基于 Linux I2C 驱动读取AP3216C传感器
  20. 计算机毕业设计源码—SpringBoot+Vue鲜花商城

热门文章

  1. 中国人民银行清算总中心:平均年龄27岁的开发团队
  2. [FROM WOJ]#3775 次小生成树
  3. html超链接代码(持续更新中)
  4. JavaScript实现的水果忍者游戏,支持鼠标操作 1
  5. iOS本地闹钟提醒实现
  6. linux下Anti Vir Linux杀毒软件的安装
  7. 计算机组成原理之CPU的构造和原理
  8. 麒麟9000和鸿蒙系统,华为P50外观曝光!首发麒麟9000L与鸿蒙OS系统
  9. 设置img的默认图片
  10. Windows 系统禁用 RC4 密码套件 windows