2016美团研发工程师笔试题(让人头疼的两个数字)
2017-03-19 19:05
387 查看
前言
博客停止更新一个多月了,之前还下定决心说每周一篇面试题相关的博客的,不过 16 年 12 月到 现在 17 年 3 月过得还是挺充实的,而且也从中学习到了很多;特别在没更新博客这一段时间了,试过了三天只睡了 12 个小时,只为心里的那份信仰。好了,不扯淡了,之后继续更新博客,现在(2017年3月19日00:13:32) 12 点了,看了一些面试题,最终选了 2016 美团研发工程师笔试题的其中一道题来写这篇博客。题目
从2到5中选两个数,第一个数较大,将两数之和告诉甲,两数之差告诉乙,两个人根据自己手上的数都算不出来答案,求这两个数分别是多少?A. 4,3
B. 5,3
C. 5,2
D. 4,2
解题
看到这题,第一个想法就是排除法来解了,那么,我们一个一个答案来分析:A 选项中,甲得到的两数之和为 7 , 乙得到的两数之差为 1 ,因此甲从 2 到 5 这四个数中,能组成两数之和为 7 的组合有 (5 , 2) 和 (4 , 3) ,乙组成两数之差为 1 的组合有 (3 , 2) , (4 , 3) 和 (5 , 4) ,因此两个人都算不出答案
B 选项,两数为 5 和 3,因此两数之和为 8 ,甲得到数为 8 ,可以猜到的组合就只有 (5 , 3)了,因为题目是说明甲乙两个人都算不出答案,因此排除 B 选项
C 选项中,两数为 5 和 2 ,因此两数之差为 3 ,乙得到的数为 3 ,从 2 到 5 中的组合就只有(5 , 2),因此排除 C
D 选项中,两数和为 6,组合只有 (4 , 2) , 所以排除 D
拓展
上面的题目是不是挺简单的,那么来拓展一下,看一道类似的经典题目【鬼谷子问徒】孙膑,庞涓都是鬼谷子的徒弟。一天鬼谷子出了这道题目:
他从 2 到 99 中选出两个不同的整数,把积告诉孙膑,把和告诉庞涓;
庞涓说:我虽然不能确定这两个数是什么,但是我肯定你也不知道这两个数是什么。
孙膑说:我本来的确不知道,但是听你这么一说,我现在能够确定这两个数字了。
庞涓说:既然你这么说,我现在也知道这两个数字是什么了。
请问这两个数字是什么?为什么?
这道题目一定要看,用上面的方法解决太麻烦了吧,先直接写个穷举来看下答案吧
package com.liangdianshui; /** * <p>鬼谷子问徒[经典] 孙膑,庞涓都是鬼谷子的徒弟。一天鬼谷子出了这道题目: 他从2到99中选出两个不同的整数,把积告诉孙膑,把和告诉庞涓; * 庞涓说:我虽然不能确定这两个数是什么,但是我肯定你也不知道这两个数是什么。 * 孙膑说:我本来的确不知道,但是听你这么一说,我现在能够确定这两个数字了。 * 庞涓说:既然你这么说,我现在也知道这两个数字是什么了。 请问这两个数字是什么?为什么? * </p> * * @author Administrator * */ public class DigitalProblem { public static void main(String[] args) { for (int n = 6; n < 200; ++n) // 穷举和的可能,最大不超过200 { // 其和能同时满足条件1和3者即为结果 if (p1(n) && p3(n)) { // 找出对应解 for (int t = 2; t * 2 < n; ++t) { if (p2(t * (n - t))) // 分拆结果符合条件2就输出 System.out.println("(" + t + "," + (n - t) + ")"); } } } } /** * 是否是唯一分解 * * @param n * @param nMax * 最大值为100 * @return */ public static boolean isOnlySolve(int n, int nMax) { int nRet = 0; // 记录满足本条件数 for (int i = 2; i * i < n; ++i) { if (n % i == 0 && n / i < nMax) if (++nRet > 1) { return false; } } return true; } /** * sum的任意和的分拆之积不可能有唯一分解,否则对方可能猜出 * <p> * 我虽然不能确定这两个数是什么,但是我肯定你也不知道这两个数是什么。 * </p> * * @param sum * @return */ public static boolean p1(int sum) { if (sum < 6) return false; for (int t = (sum - 1) / 2; t > 1; --t) { if (isOnlySolve(t * (sum - t), 100)) return false; } return true; } /** * 只有一种积的分拆满足 p1 * <p> * 我本来的确不知道,但是听你这么一说,我现在能够确定这两个数字了 * </p> * * @param times2 * @return */ public static boolean p2(int times2) { int nRet = 0; // 记录满足本条件数 for (int nd = 2; nd * nd < times2; ++nd) { if (times2 % nd == 0 && p1(nd + times2 / nd)) if (++nRet > 1) return false; } return true; } /** * 只有一种和的分拆满足 p2 * <p> * 既然你这么说,我现在也知道这两个数字是什么了 * </p> * * @param sum * @return */ public static boolean p3(int sum) { int nRet = 0; // 记录满足本条件数 for (int t = (sum - 1) / 2; t > 1; --t) { if (p2(t * (sum - t))) if (++nRet > 1) return false; } return true; } }
运行的结果为:
有人直接逻辑推理出来的吗?在评论那里写下可好,让我学习学习
相关文章推荐
- 2016美团研发工程师笔试题(让人头疼的两个数字)
- 微策略2011校园招聘笔试题(找出数组中两个只出现一次的数字)
- 盛大笔试:两个有序数组的中间大小的数字
- 笔试面试成对出现的一组数,只有一个或两个只出现一次的数字,找到它们。
- 笔试题:输入两个正整数a和b,然后分别将他们的数字按照高位在右边的 方式反转后求和!
- 笔试算法题(18):常数时间删除节点 & 找到仅出现一次的两个数字
- 拼多多内推笔试二:数字字符串两个字符串相乘/大数相乘
- 微策略2011校园招聘笔试题(找出数组中两个只出现一次的数字)
- 笔试面试成对出现的一组数,只有一个或两个只出现一次的数字,找到它们。
- [笔试题]黑板上写下50个数字,选两个黑板上数字a和b,在黑板写|b-a|,剩下的数字?
- 笔试题(1)--两个线程交叉打印递增数字,用synchronized和wait实现
- 笔试训练-一个整型数组里除了两个数字之外,其他的数字都出现了两次
- (笔试中的题目)一个已经排序好的数组找到两个数字相加等于一个给定的数
- 一个数组中只有两个数字是出现一次,其他所有数字都出现了两次。找出这两个数字,编程实现。
- 【华为2018年校招笔试】找两个字符串的最大公共子串
- 一个整型数组里除了一个或者两个或者三个数字之外,其他的数字都出现了两次。请写程序找出这两个只出现一次的数字。要求时间复杂度是O(n),空间复杂度是O(1)
- 经典指针程序,互换两个数字
- 2014年去哪儿网笔试题--一个10*10的矩阵(可以理解为棋盘),随时生成一组数据填入矩阵,任何一个位置的数字除4进行计算,按余数着色...
- 找出数组中两个只出现一次的数字
- 如何用JS判断两个数字的大小