1. 赛马找最快
1.1 - 25匹马5条跑道找最快的3匹马,需要跑几次? 7
将25匹马分成ABCDE 5组,假设每组的排名就是A1>A2>A3>A4>A5,用边相连,这里比赛5次;
第6次,每组的第一名进行比赛,可以找出最快的马,这里假设A1>B1>C1>D1>E1,D1、E1肯定进不了前3,直接排除掉,D、E剩下的也排除;
第7次,第一名那组的二三名 A2 A3、第二名那组的第一二名 B1 B2、第三名C1, 即 B1 C1 A2 B2 A3 比赛,可以找出第二,第三名;
所以最少比赛需要 7 次。
1.2 - 64匹马8条跑道找最快的4匹马,需要跑几次? 11
---
---
1、全部马分为8组,每组8匹,每组各跑一次,然后淘汰掉每组的后四名,如下图(需要比赛 8 场)
2、取每组第一名进行一次比赛,然后淘汰最后四名所在组的所有马,如下图(需要比赛1场)
这个时候总冠军已经诞生,它就是A1,蓝色区域(它不需要比赛了),而其他可能是前四名的只可能是下图中的黄色区域了(A2,A3,A4,B1,B2,B3,C1,C2,D1,共9匹马)
3、只要从上面的 9 匹马中找出跑得最快的三匹马就可以了,但是现在只有8个跑道,那就随机选出 8 匹马进行一次比赛吧(需要比赛 1 场)
4、上面比赛完,选出前三名,与剩下的一匹马进行比赛,选出前三名,即为第二三四名(需要 1 场比赛)
1.3 - 25匹马5条跑道找最快的5匹马,需要跑几次? 最少8次最多9次
(1) 首先将25匹马分成5组,并分别进行5场比赛之后得到的名次排列如下:
A组: [A1 A2 A3 A4 A5]
B组: [B1 B2 B3 B4 B5]
C组: [C1 C2 C3 C4 C5]
D组: [D1 D2 D3 D4 D5]
E组: [E1 E2 E3 E4 E5]
其中,每个小组最快的马为[A1、B1、C1、D1、E1]。
(2) 将[A1、B1、C1、D1、E1]进行第6场,选出第1名的马,不妨设 A1>B1>C1>D1>E1. 此时第1名的马为A1。
(3) 将[A2、B1、C1、D1、E1]进行第7场,此时选择出来的必定是第2名的马,不妨假设为B1。因为这5匹马是除去A1之外每个小组当前最快的马。
(3) 进行第8场,选择[A2、B2、C1、D1、E1]角逐出第3名的马。
(4) 依次类推,第9,10场可以分别决出第4,5名的马。
因此,依照这种竞标赛排序思想,需要10场比赛是一定可以取出前5名。
但是还能继续减少比赛场次,优化后最少8次最多9次就能得到结果,详细过程见参考地址。
2. 天平称重问题
2.1 - 8个乒乓球,其中一个比其他重,有一个秤,问至少几次能够找出重的那个乒乓球? 2
2 次,分成3堆:3-3-2。
① 称3和3,如果一样重,代表重的在2。
② 称2个那一堆的。
或
① 称3和3,不一样重,重的在3里面重的那堆。
② 3个里面随便取2个,一样重,第三个重,不一样重,重的那个就是。
2.2 - 有一个天平,九个砝码,其中一个砝码其他轻,问至少要称几次才能找到轻的? 2
2 次,分成3堆:3-3-3。
天平一边放三个砝码,哪边轻就在哪边,一样重就在剩下的三个砝码中;
现在已经锁定了三个砝码,天平一边放一个,哪边轻是哪个,一样重就是剩下的那个。
2.3 - 有十组砝码每组十个,每个砝码重10g,其中一组每个只有9g,有能显示克数的秤最少几次能找到轻的那一组砝码? 1
称一次即可,因为能显示克数;
将砝码分组编号1~10, 第1组拿1个砝码、第2组拿2个…第10组拿10个,共55个,全部放到秤上计算总克数X;Y = (1*10 + 2 * 10 + … + 10 * 10) - X = 550 - X,Y即为轻的那组的编号,用轻了的重量来反应组别数。
2.4 - 有20瓶药丸,其中19瓶装有1克/粒的药丸,余下一瓶装有1.1克/粒的药丸。给你一台称重精准的天平,怎么找出比较重的那瓶药丸?天平只能用一次;
从药瓶#1取出一粒药丸,从药瓶#2取出两粒,从药瓶#3取出三粒,依此类推。
如果每粒药丸均重1克,则称得总重量为210克(1 + 2 + … + 20 = 20 * 21 / 2 = 210),“多出来的”重量必定来自每粒多0.1克的药丸。
药瓶的编号可由算式(weight - 210) / 0.1 得出。因此,若这堆药丸称得重量为211.3克,则药瓶#13装有较重的药丸。
2.5 - 有7克、2克砝码各一个,天平一只,如何只用这些物品五次内将140克的盐分成50、90克各一份?
第一次:先分成70和70(140 = 70 + 70)
第二次:通过 7 和 2 砝码将70分成 9 和 61(70 = 2 + 7 + 61)
第三次:通过 9克盐 和 2克砝 码将61分成 50 和 11 (61 = 2 + 9 + 50)
3. 硬币翻转问题
有23枚硬币在桌上,10枚正面朝上。蒙住你的眼睛对硬币进行分组,如何让左右两组硬币正面朝上的一样多?
将其分为一堆10个、另一堆13个,然后将10个那一堆所有的硬币翻转就可以了,两边的就一样多了。
原理:假设13个一堆中有X个正面的,则10个一堆的有10-X个正面的。这时把10个一堆的全部翻转,则正面的成反面,反面的成正面,这时正面的有10-(10-X)个,即X个,13个一堆中有X个正面,10个一堆中也有X个正面,X=X,所以符合题目要求。
4. 过桥/过河问题
4.1 - 最快过桥
在一个夜晚,同时有4人需要过一桥,一次最多只能通过两个人,且只有一只手电筒,而且每人的速度不同。A,B,C,D需要时间分别为:1,2,5,10分钟。问:在17分钟内这四个人怎么过桥?
第一次:A + B过桥(2分钟)+ B回去(2分钟)= 4 分钟
第二次:C + D过桥(10分钟)+ A回去(1分钟)= 11 分钟
第三次:A + B过桥(2分钟)
一共:2 + 2 + 10 + 1 + 2 = 17分钟
4.2 - 人鬼过河
有三个人跟三个鬼要过河,河上没桥只有条小船,然后船一次只能渡一个人和一个鬼,或者两个鬼或者两个人,无论在哪边岸上,只有是人比鬼少的情况下,人会被鬼吃,然而船又一定需要人或鬼操作才能航行(要有人或鬼划船),问,如何安全的把三人三鬼渡过河对岸?
人人人鬼--鬼--鬼
人人人--鬼--鬼鬼
人鬼-人鬼--人鬼
鬼鬼-鬼--人人人
鬼-鬼--鬼人人人
先两鬼过去,一鬼回来。对面有一鬼,这边有三人两鬼。
再两鬼过去,一鬼回来。对面有两鬼,这边有三人一鬼。
再两人过去,一人一鬼回来。对面一人一鬼,这边两人两鬼。
最后两人过去,一鬼回来。对面三人,这边三鬼。
剩下的就三个鬼,二个过去,一个回来接另外一个。
5. 二进制问题
5.1 - 毒药问题
有1000个一模一样的瓶子,其中有999瓶是普通的水,有1瓶是毒药。任何喝下毒药的生命都会在一星期之后死亡。现在你只有10只小白鼠和1个星期的时间,如何检验出哪个瓶子有毒药?
首先一共有1000瓶,2的10次方是1024,刚好大于1000, 也就是说,1000瓶药品可以使用10位二进制数就可以表示。
从第一个开始:
第一瓶 : 00 0000 0001
第二瓶 : 00 0000 0010
第三瓶 : 00 0000 0011
……
第999瓶: 11 1111 0010
第1000瓶:11 1111 0011
需要十只老鼠,如果按顺序编号,ABCDEFGHIJ分别代表从低位到高位每一个位。 每只老鼠对应一个二进制位,如果该位上的数字为1,则给老鼠喝瓶里的药。 观察,若死亡的老鼠编号为:ACFGJ,一共死去五只老鼠,则对应的编号为 10 0110 0101, 则有毒的药品为该编号的药品,转为十进制数为:613号。
5.2 - 分金块问题
工人为老板打工,工作七天可以获得一块金子,工人每天可以分得一点金子,老板必须每天发金子,不能多给,也不能少给,把这个金子切两刀,就可以每天给工人发工资,请问怎么切?
切两刀将金子分成三份,1/7、2/7、4/7;
工作第一天 把1/7分给工人;
工作第二天 把2/7分给工人,并要回1/7那块金子,工人有2/7的金子;
工作第三天 把1/7给工人,工人有3/7金子;
工作第四天 把前两块金子要回,给工人4/7的金子 工人有4/7的金子;
工作第五天 把1/7分给工人 工人有5/7的金子;
工作第六天 把2/7分给工人,并要回1/7那块金子,工人有6/7的金子;
工作第七天 把1/7给工人,工人有完整的金子;
扩展:如何给工人发15天的工资?把金块分成1/15、2/15、4/15、8/15。
6. 先手必胜问题
6.1 - 轮流拿石子
一共有 N 颗石子,每次能取1~M颗,A,B轮流取,最后一次将石头取完的人获胜,谁最后会获胜?(假设他们每次都取最优解)。
假如A先取,N<M,A获胜;
N>M,若N能被(M + 1)整除时,A失败;
若N不能被(M + 1)整除时,A获胜;
假如B先取,(同上);
再说分析:
还是以 A 先手为例,N < M 时 A 一次拿完(不可能给B留机会,前提就是每次取最优),不会给B留机会;
N > M时,A要想赢,必须要在自己倒数第二次取完的时候还剩下(M + 1)颗石子(此时A和B还可以再取一次就可以分出胜负游戏就结束了),这样不论B取几颗,A都获胜!但是要怎样才能控制最后一轮的石子数量?
分两种情况分析,
- N不能被(M + 1)整除,A先拿走n颗石子(使得剩下的石子数量是(M + 1)的整数倍),那么下一次B拿走k颗石子时,A就拿走(M + 1)- k颗石子。这样不论B怎么拿A总能控制剩下的石子数量是(M + 1)的整数倍,那么最后一轮一定剩下(M + 1)颗石子;
- N能被(M + 1)整除,A就认输吧。。。(B除非傻才会让A赢)无论A怎么拿,B可以控制石子数量(即当B拿完后总能使剩下的石子数量是(M + 1)的整数倍),在最后一轮之前B拿完后还剩(M + 1)颗,A拿多少颗都是输。
6.2 - 抢30
抢 30 是双人游戏,游戏规则是:第一个人喊“ 1 ”或“ 2 ”,第二个人要接着往下喊一个或两个数,然后再轮到第一个人。两人轮流进行下去,最先喊 30 的人获胜,问喊数字的最佳策略。
尽量喊3的倍数,就能赢;
解析: 倒着看,其实,喊 27 时,就决定胜负了。
假设 A 喊了 27,B只能喊 28 或 29 , 下个回合,A 一定可以喊30。也就是说,喊 27 者必胜。
再倒着看,其实喊 24 时,就定胜负了。假设 A 喊了 24 ,B 只能喊 25 或 26 , 下个回合 A 一定能喊 27 。
由于喊 27 者必胜,因此喊 24 者也必胜。
同理可以推出:喊 3 的倍数者必胜。
然后就会发现,这个游戏,谁先喊,谁一定输。
6.3 - 最后一次拿书
100本书,两个人轮流拿,每次能够拿1~5本,怎么拿能保证最后一次是你拿?
如果最后一次是我拿,那么上回合最少剩下6本;
只要保持每个回合结束后都剩下6的倍数,且在这个回合中我拿的书和对方拿的书加起来为6本;第一次我必须先手拿4本(100 % 6 = 4),这不算在第一回合内。即第一次拿4个,之后对方1个,我拿5个,对方拿2个,我拿3个,总是对方拿n个,我拿6-n个.
因为第一次以后剩下96个,每次使得两个人拿的总数是6,那么最后就是我拿的。
7. 推理题
7.1 - 掰巧克力问题
一块N * M大小的巧克力,每次掰一块的一行或一列,全部掰成 1 * 1 大小的巧克力需要掰多少次?
N * M - 1次;先(M-1)次分成M块,M块重复(N-1)次,即(M-1)+M(N-1) = M*N-1
不管怎么掰,每次只能把一个大块掰成两个小块,即每次掰只能增加1块巧克力; 那么将1块巧克力掰成 N * M 块小巧克力就需要掰N * M - 1次。
7.2 - 辩论赛问题
1000个人参加辩论赛,1对1进行辩论,淘汰输掉的一方,问需要安排多少场比赛才能角出冠军?
每场辩论赛只能淘汰一个人,要淘汰999个人则需要安排999场比赛。
7.3 - 在24小时里面时针分针秒针可以重合几次
24小时中时针走2圈,而分针走24圈,时针和分针重合24-2=22次, 而只要时针和分针重合,秒针一定有机会重合,所以总共重合22次。
由于时针1分钟旋转的圆心角度数为0.5度,分针1分钟旋转的圆心角度为6度,当两针第一次重合时后到第二次重合,分针比时针多旋转过的圆心角度数为360度,设两针再次重合需要的时间为 t,则 6t - 0.5t = 360,t = 65+5/11分钟。
根据以上计算,每隔 65+5/11 分时针和分针重合一次。
即,从12点开始,每经过65+5/11 分,时针与分针重合一次, 全天共重合 22次 。 一昼夜有24×60=1,440(分),所以两针一昼夜重合22(次)。
重合次数=1440/(65+5/11)=22次
7.4 - N只蚂蚁走树枝,问总距离或者总时间
放N只蚂蚁在一条长度为M树枝上,蚂蚁与蚂蚁之间碰到就各自往反方向走,问总距离或者时间为多少?
- 蚂蚁相碰就往反方向走,可以直接看做没有发生任何事,大家都相当于独立的
- A蚂蚁与B蚂蚁相碰后你可以看做没有发生这次碰撞,这样无论是求时间还是距离都很简单了。
有一辆火车以每小时15公里的速度离开洛杉矶直奔纽约,另一辆火车以每小时20公里的速度从纽约开往洛杉矶。如果有一只鸟,以30公里每小时的速度和两辆火车现时启动,从洛杉矶出发,碰到另一辆火车后返回,依次在两辆火车来回的飞行,直到两辆火车相遇,请问,这只小鸟飞行了多长距离?
假设洛杉矶到纽约的距离为 s
那小鸟飞行的距离就是 ( s / ( 15 + 20 ) ) ∗ 30
7.5 - 旅馆的1元钱问题
有三个人去住旅馆,住三间房,每一间房10元,于是他们一共付给老板30,第二天,老板觉得三间房只需要25元就够了于是叫小弟退回5给三位客人,谁知小弟贪心,只退回每人1,自己偷偷拿了2,这样一来便等于那三位客人每人各花了九元,于是三个人一共花了27,再加上小弟独吞了不2,总共是29。可是当初他们三个人一共付出30那么还有1元呢?
他们所消费的27元里已经包括小弟贪污的2元了,再加退还的3元=30元; 这30元现在的分布是:老板拿25元,伙计拿2元,三人各拿1元,正好!
8. 数字问题
8.1 - 随机数
给定生成1到5的随机数Rand5(),如何得到生成1到7的随机数函数Rand7()?
rand() 产生0到最大整数的任意一个整数,那么 rand() % (b-a+1)+ a 就表示 a~b 之间的一个随机整数。即如果要产生1~5,则是这样:int num = rand() % 5 + 1;
由rand5() 产生rand7()方法为:
用5*(rand5()-1) + rand5()可以生成1到25之间的随机数。我们可以只要1到21(3*7)之间的数字可以等概率得到1~7;
int rand7(){ int x = 22; while(x > 21){ x=5*(rand5()-1)+rand5(); } return x%7+1; }
另一种方法:
x = rand() + rand5()-1; 等概率得到1~9的随机数,只需要取1~7
int rand7(){ int x = 8; while(x > 7){ x = rand() + rand5()-1; // 等概率得到1~9的随机数,只需要取1~7 } return x % 7+1; }
8.2 - 11223344问题
有8个数,11223344,将其排列,要求结果满足:两个1之间有一个数,两个2之间有两个数,两个3之间有三个数,两个4之间有四个数。问这个结果是多少?
41312432 或 23421314
先填 4 比较好,因为填 4 的可能方案最少。
由于方案 1 和方案 3 只是顺序不同,因此我们可以只考虑方案1,如果最后以方案1为开始找到了答案,逆序一下便是方案3能找到的答案。因此,我们只需考虑方案 1 和方案 2 。
接下来按照上面的思路,填 3 ,再填 2 ,最后填 1 。最终便可搜索到答案。
逆序后为:23421314
9. 水桶问题
9.1 - 水资源无限,3L和5L水桶各一个,怎样取4L的水?
装满5L水,倒满3L中,5L桶剩2L;
将2L倒进3L桶,余1L空位;
将5L桶装满,倒满3L桶,还剩4L在5L桶中。
9.2 - 水资源无限,5L和6L水桶各一个,怎样取3L的水?
装满5L桶,全部倒进6L桶,余1L水位;
再装满5L桶,将剩下6L补充满,则5L桶剩4L;
将4L水倒进6L桶,余2L空位;
再装满5L桶,补满6L桶,还剩3L在5L桶中。
9.3 - 一个装了10L水的桶,一个7L的空桶,一个3L的空桶,怎样变成2个5L?
10L桶 | 7L桶 | 3L桶 |
---|---|---|
10 | 0 | 0 |
3 | 7 | 0 |
3 | 4 | 3 |
6 | 4 | 0 |
6 | 1 | 3 |
9 | 1 | 0 |
9 | 0 | 1 |
2 | 7 | 1 |
2 | 5 | 3 |
5 | 5 | 0 |
9.4 - 只有两个舀酒的勺子,分别能舀7两和11两酒,如何舀出2两酒?
7两勺 | 11两勺 |
---|---|
0 | 11 |
7 | 4 |
0 | 4 |
4 | 0 |
4 | 11 |
7 | 8 |
0 | 8 |
7 | 1 |
0 | 1 |
1 | 11 |
7 | 5 |
0 | 5 |
5 | 0 |
5 | 11 |
7 | 9 |
0 | 9 |
7 | 2 |
10. 计时问题
10.1 - 有一个能计时6分钟的小沙漏和一个能计时8分钟的大沙漏,如何计时10分钟?
两个沙漏同时倒置开始计时,等小沙漏漏完,大沙漏还剩2分钟,这时倒置小沙漏继续计时;
大沙漏漏完小沙漏还剩4分钟,再把大沙漏倒置继续计时;
小沙漏漏完大沙漏还剩4分钟,这时准备工作已经完毕;
等待大沙漏漏完(4分钟)+ 小沙漏(6分钟) = 10分钟。
10.2 - 烧一根绳子需要一个小时,现有若干条相同的绳子,问如何计时15分钟?
点燃绳子A的一头,同时点燃绳子B的两头;
绳子B烧完的时候绳子A还剩一半,此时点燃绳子A的另一头开始计时;
15分钟后绳子A烧完。
11. 灯泡开关问题
11.1 - 在房里有三盏灯,房外有三个开关,在房外看不见房内的情况,你只能进门一次,你用什么方法来区分那个开关控制那一盏灯?
打开一个开关,过10分钟后关掉开关,并打开另一个开关。
进屋确认可知:
亮着的灯是由第二次打开的开关控制;
摸上去发热的不发亮的灯是由第一次打开的开关控制
剩下的第三盏灯是由未操作过的开关控制。
11.2 - 一个圆环上有 100 个灯泡,灯泡有亮和暗两种状态。按一个灯泡的开关可以改变它和与它相邻两个灯泡的状态。设计一种算法,对于任意初始状态,使所有灯泡全亮。
将灯泡编号 1 ~ 100。
步骤一:将灯泡变为全亮或只剩一个为暗
从 1 循环到 98 ,遇到暗的则按它下一个,使之变亮。循环完毕,1 ~ 98 必然全亮。99 和 100可能为亮亮、暗亮、亮暗、暗暗四种状态。
若为亮亮,满足题目要求;
暗亮、亮暗,达到只剩一个为暗的状态;
若为暗暗,则按下编号 100 的灯泡,使编号 99 、100 变为亮,编号 1 的灯泡变为暗,从而达到只剩一个为暗的状态。
步骤二:将灯泡变为全暗
由于灯泡环形摆放,我们指定暗的灯泡编号为 1 ,将剩下 99 个亮着的灯泡每 3 个为一组。按下每组中间的灯泡后,使得所有灯泡变为暗。
步骤三:将灯泡变为全亮
将所有灯泡按一下,灯泡变为全亮。(全暗 <=> 全亮。全暗和全亮状态可以相互转化,方法就是将每个灯泡按一次。这样每个灯泡都被改变了 3 次状态,使得全暗变为全亮,全亮也可变为全暗。)
11.3 - 对于 N 个灯泡的任意初始状态 ( N > 3 ) ,能否经过若干次操作使得所有灯泡全亮?
N = 3k+1 一定可以。方法与上述步骤相同,在步骤二中可以将3k个亮的灯泡分为k组。
N = 3k+2 一定可以。将上述步骤一目标状态的只剩一个为暗改成剩两个相邻为暗,其余 3 * k 个灯泡分组按即可。因为,对于任意只剩一个为暗的状态,按下该灯泡左右任意一个就可以变成剩两个相邻为暗的状态!
N = 3k 不一定。如果经过上述步骤一可以将灯泡变成全亮的状态则有解;否则,无解。