女友校招笔试编程题:网易测试岗-买苹果和求最大奇约数
2016-09-17 11:14
375 查看
嗯,这算是人生中第一次正式写博客吧。以前一直将笔记记录到网络笔记本上,自己没事的时候会翻翻笔记回顾总结一下自己。
但是前段时间在某个场合提到了“技术需要分享”,嗯,是的,技术需要分享,想来自己也看不少大牛的技术博客,大牛一般都是非常乐于分享自己的技术的!作为一个小菜鸟,我也要像技术大神们学习,分享菜鸡的技术成长历程。一是希望通过自己的分享尽量能够帮助到一些人,同时希望在这个过程中能够提升自己的语言组织与逻辑表达能力。
文章中肯定会有或大或小的错误,希望读到我文章的朋友能够在评论里及时指明,我会第一时间给改正!以前比较少写正规的文章,做笔记的时候比较随意,格式排版配图什么的可能刚开始不太好,但凡事总有开始,肯定会越来越好的。
顺便提一嘴,我目前使用的语言是Java。
好了,不瞎BB了,分享技术,享受技术!go~
女友最近在找工作,参加各种公司的校招,每次笔试完后都会和我分享其中的一些题目,中秋放假做一个算是阶段性总结的总结吧!
第一题:
[编程题] 买苹果
时间限制:c/c++,1s,其他语言3s
空间限制:32768K,其他语言忘记了...
题目描述:
小易去附近的商店买苹果,奸诈的商贩使用了捆绑交易,只提供6个每袋和8个每袋的包装(包装不可拆分)。
可是小易现在只想购买恰好n个苹果,小易想购买尽量少的袋数方便携带。
如果不能购买恰好n个苹果,小易将不会购买。
输入描述:
输入一个整数n,表示小易想购买n(1 ≤ n ≤ 100)个苹果
输出描述:
输出一个整数表示最少需要购买的袋数,如果不能买恰好n个苹果则输出-1
输入样例:
20
输出样例:
3
解析:这道题不难,就是考察2元一次方程的最值问题,中学生都会.....
设,容量为6的袋子数量为a,容量为8的袋子的数量为b,使用的袋子总数为x,则以上问题可由如下方程组表示:(请忽略很丑的字体,重点是内容)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202008/19/2acf189a3629ed4c711fdf4166644f9b)
然后,用b表示a,经过一些运算可以得到如下结果:(请忽略很丑的字体,重点是内容)
![](https://oscdn.geek-share.com/Uploads/Images/Content/202008/19/51d206a36239bc4d255ebe27948f88cd)
再然后,需要注意的是,因为是要求x的最小值,所以当b最大时,x最小,所以实现时需要注意一下,b从最大的可选值开始取就可以了。
然后根据上面的思路就可以进行代码实现啦!具体代码如下:
第二题:
[编程题|20分] 最大的奇约数
时间限制:c/c++,1s,其他语言3s
空间限制:32768K,其他语言忘记了...
题目描述:
大的奇约数
小易是一个数论爱好者,并且对于一个数的奇数约数十分感兴趣。一天小易遇到这样一个问题:
定义函数 f(x) 为 x 最大的奇数约数,x为正整数。 例如:f(44) = 11.
现在给出一个N,需要求出 f(1) + f(2) + f(3)…….f(N)
例如: N = 7
f(1) + f(2) + f(3) + f(4) + f(5) + f(6) + f(7) = 1 + 1 + 3 + 1 + 5 + 3 + 7 = 21
小易计算这个问题遇到了困难,需要你来设计一个算法帮助他。
输入描述:
输入一个整数N (1 ≤ N ≤ 1000000000)
输出描述:
输出一个整数,即为f(1) + f(2) + f(3)…….f(N)
输入样例:
7
输出样例:
21
解析:这道题的解题过程也是充满了艰辛......
当时的解题过程是这样的:
首先,先对n以内的所有奇数直接用公式求和。
其次,就考虑偶数的情况,偶数分两种:2的n次幂的数和非2的n次幂的数。设这个偶数为a,对a进行开方,这个开方的结果也分两种:整数和浮点数。如果开方的结果是整数,则判断是奇数还是偶数,如果是奇数则返回,如果是偶数则对Math.sqrt(a)递归这个操作。如果开方的结果是浮点数,则对a / 2递归这个操作。这样就可以得出结果。下面是实现的代码。下面的图是当时的推导过程,有些乱,大家可以自己拿草纸推导一下。
![](https://oscdn.geek-share.com/Uploads/Images/Content/202008/19/dad0e4a1c81b29cde3e97dcc7e880e35)
是的,正如上面的代码中注释的那样,提交之后,结果超时了......代码的循环次数其实并不多的,但是“时间复杂度”这个东西嘛,也是要考虑某个操作的耗时情况的。正如上面代码中的注释那样,Math.sqrt()方法是很耗时的,读者朋友们可以自己打开注释去看看,开方运算占用了大部分的运算时间。既然这样都不行,那只有一种可能,这个东西真的是有公式或者说规律的。好那现在就来分析怎么找规律......
设sum(i) = f(1) + f(2) + ... + f(i);
求sum(i)的过程中,对于f(i), i 为奇数可以直接求,就是 i 本身。
问题就是求所有f(i), i为偶数的和。
因为要求的是最大奇约数,
所以f(2k) = f(k) + 1 + 3 + ... + 2k - 1 ,
所以f(2) + f(4) + ... + f(2k) = f(1) + f(2) + ... + f(k) + 1 + 3 + ... + 2k - 1
所以
当i 为偶数时,sum(i) = sum (i / 2) + 1 + 3 + ... + i - 1
当i 为奇数时,sum(i) = sum (i - 1) + i
所以,根据这个思想,代码如下:
这样,终于完成了这道题。
ps:第一次写技术类博客,各种经验不足,图片也不会插入,排版也不太熟,写了好久,不足之处还请指出,非常感谢,我自己之后也会把现在不足的地方改正。
但是前段时间在某个场合提到了“技术需要分享”,嗯,是的,技术需要分享,想来自己也看不少大牛的技术博客,大牛一般都是非常乐于分享自己的技术的!作为一个小菜鸟,我也要像技术大神们学习,分享菜鸡的技术成长历程。一是希望通过自己的分享尽量能够帮助到一些人,同时希望在这个过程中能够提升自己的语言组织与逻辑表达能力。
文章中肯定会有或大或小的错误,希望读到我文章的朋友能够在评论里及时指明,我会第一时间给改正!以前比较少写正规的文章,做笔记的时候比较随意,格式排版配图什么的可能刚开始不太好,但凡事总有开始,肯定会越来越好的。
顺便提一嘴,我目前使用的语言是Java。
好了,不瞎BB了,分享技术,享受技术!go~
女友最近在找工作,参加各种公司的校招,每次笔试完后都会和我分享其中的一些题目,中秋放假做一个算是阶段性总结的总结吧!
第一题:
[编程题] 买苹果
时间限制:c/c++,1s,其他语言3s
空间限制:32768K,其他语言忘记了...
题目描述:
小易去附近的商店买苹果,奸诈的商贩使用了捆绑交易,只提供6个每袋和8个每袋的包装(包装不可拆分)。
可是小易现在只想购买恰好n个苹果,小易想购买尽量少的袋数方便携带。
如果不能购买恰好n个苹果,小易将不会购买。
输入描述:
输入一个整数n,表示小易想购买n(1 ≤ n ≤ 100)个苹果
输出描述:
输出一个整数表示最少需要购买的袋数,如果不能买恰好n个苹果则输出-1
输入样例:
20
输出样例:
3
解析:这道题不难,就是考察2元一次方程的最值问题,中学生都会.....
设,容量为6的袋子数量为a,容量为8的袋子的数量为b,使用的袋子总数为x,则以上问题可由如下方程组表示:(请忽略很丑的字体,重点是内容)
然后,用b表示a,经过一些运算可以得到如下结果:(请忽略很丑的字体,重点是内容)
再然后,需要注意的是,因为是要求x的最小值,所以当b最大时,x最小,所以实现时需要注意一下,b从最大的可选值开始取就可以了。
然后根据上面的思路就可以进行代码实现啦!具体代码如下:
import java.util.Scanner; public class wangyi1 { public static void main(String[] args) { Scanner scan = new Scanner(System.in); while (scan.hasNext()) { int n = scan.nextInt(); System.out.println(getSum(n)); } } public static int getSum(int n) { int sum = -1; int a = 0; int b = 0; int m = n / 8; for (int i = m; i >= 0; i--) { if ((n - 8 * i) % 6 == 0) { b = (n - 8 * i) / 6; a = i; sum = a + b; break; } } return sum; } }
第二题:
[编程题|20分] 最大的奇约数
时间限制:c/c++,1s,其他语言3s
空间限制:32768K,其他语言忘记了...
题目描述:
大的奇约数
小易是一个数论爱好者,并且对于一个数的奇数约数十分感兴趣。一天小易遇到这样一个问题:
定义函数 f(x) 为 x 最大的奇数约数,x为正整数。 例如:f(44) = 11.
现在给出一个N,需要求出 f(1) + f(2) + f(3)…….f(N)
例如: N = 7
f(1) + f(2) + f(3) + f(4) + f(5) + f(6) + f(7) = 1 + 1 + 3 + 1 + 5 + 3 + 7 = 21
小易计算这个问题遇到了困难,需要你来设计一个算法帮助他。
输入描述:
输入一个整数N (1 ≤ N ≤ 1000000000)
输出描述:
输出一个整数,即为f(1) + f(2) + f(3)…….f(N)
输入样例:
7
输出样例:
21
解析:这道题的解题过程也是充满了艰辛......
当时的解题过程是这样的:
首先,先对n以内的所有奇数直接用公式求和。
其次,就考虑偶数的情况,偶数分两种:2的n次幂的数和非2的n次幂的数。设这个偶数为a,对a进行开方,这个开方的结果也分两种:整数和浮点数。如果开方的结果是整数,则判断是奇数还是偶数,如果是奇数则返回,如果是偶数则对Math.sqrt(a)递归这个操作。如果开方的结果是浮点数,则对a / 2递归这个操作。这样就可以得出结果。下面是实现的代码。下面的图是当时的推导过程,有些乱,大家可以自己拿草纸推导一下。
import java.util.Scanner; /** * 方法1:时间复杂度并不高,但是耗时过长(开方运算耗时长) * * @author Administrator * */ public class wangyi2_a { public static void main(String[] args) { Scanner scan = new Scanner(System.in); while (scan.hasNext()) { int n = scan.nextInt(); // long t1 = System.currentTimeMillis(); System.out.println(getsum(n)); // long t2 = System.currentTimeMillis(); // System.out.println("total time=" + (t2 - t1)); // System.out.println("sqrt time=" + sqrtTime); } } // static int sqrtTime = 0; static int f(int x) { if ((x & 1) == 1) { return x; } // long t1 = System.currentTimeMillis(); // 经测试,开方运算过于耗时 double sqrt = Math.sqrt(x); int k = (int) Math.floor(sqrt); int up = (int) Math.ceil(sqrt); // long t2 = System.currentTimeMillis(); // long t3 = t2 - t1; // sqrtTime += t3; if ((k & 1) == 1) { return k; } else { if (k == up) return f(k); else { return f(x >> 1); } } } static int getsum(int n) { int m = 0; int 9e91 maxj = 0; int t = 0; if ((n & 1) == 0) { m = n >> 1; maxj = n - 1; t = n; } else { m = n >> 1 + 1; maxj = n; t = n - 1; } int sum = (1 + maxj) * (m >> 2); for (int i = 2; i <= t; i = i + 2) { sum += f(i); } return sum; } }
是的,正如上面的代码中注释的那样,提交之后,结果超时了......代码的循环次数其实并不多的,但是“时间复杂度”这个东西嘛,也是要考虑某个操作的耗时情况的。正如上面代码中的注释那样,Math.sqrt()方法是很耗时的,读者朋友们可以自己打开注释去看看,开方运算占用了大部分的运算时间。既然这样都不行,那只有一种可能,这个东西真的是有公式或者说规律的。好那现在就来分析怎么找规律......
设sum(i) = f(1) + f(2) + ... + f(i);
求sum(i)的过程中,对于f(i), i 为奇数可以直接求,就是 i 本身。
问题就是求所有f(i), i为偶数的和。
因为要求的是最大奇约数,
所以f(2k) = f(k) + 1 + 3 + ... + 2k - 1 ,
所以f(2) + f(4) + ... + f(2k) = f(1) + f(2) + ... + f(k) + 1 + 3 + ... + 2k - 1
所以
当i 为偶数时,sum(i) = sum (i / 2) + 1 + 3 + ... + i - 1
当i 为奇数时,sum(i) = sum (i - 1) + i
所以,根据这个思想,代码如下:
import java.util.Scanner; /** * 方法2:动态规划方法 * * @author Administrator * */ public class wangyi2_b { public static void main(String[] args) { Scanner scan = new Scanner(System.in); while (scan.hasNext()) { int n = scan.nextInt(); System.out.println(getsum(n)); } } static int getsum(int n) { if (n == 1) { return 1; } if (n % 2 == 0) { return getsum(n / 2) + n * n / 4; } else { return getsum(n - 1) + n; } } }
这样,终于完成了这道题。
ps:第一次写技术类博客,各种经验不足,图片也不会插入,排版也不太熟,写了好久,不足之处还请指出,非常感谢,我自己之后也会把现在不足的地方改正。
相关文章推荐
- (网易2018校招笔试)[编程题] 字符串碎片
- 网易2017校招内推笔试练习卷编程题2--出专辑
- (网易2018校招笔试)[编程题] 字符串碎片
- 2017年网易校招笔试编程题第二题
- (网易2018校招笔试)[编程题] 魔法币
- 2018校招笔试题——网易编程题跳石板
- (网易2018校招笔试)[编程题]相反数
- 网易2017校招内推在线笔试编程题3
- 网易2018校招笔试编程题
- 2017校招去哪网,阿里,网易,中兴,华为笔试编程题五则(Python描述)
- 网易2018校招内推Android笔试编程题一道
- 【笔试总结】网易2019校招编程题-玩橡皮泥
- 分苹果----网易2017内推笔试编程题合集(一)
- 【Python】 网易笔试编程题( 最大的奇约数)
- 2017年网易校招笔试编程题第一题
- (网易2018校招笔试)[编程题] 相反数
- 网易2018届校招笔试-编程题
- (网易2018校招笔试)[编程题] 游历魔法王国
- (网易2018校招笔试)[编程题] 游历魔法王国
- 【Python】 网易笔试编程题(买苹果)