一些场景题

今天记录一些场景题,来源是拓跋阿秀:智力&场景题 | 阿秀的学习笔记

三人三鬼过桥问题

有 3 个人和 3 个鬼要过河,河上只有一条小船,船每次只能载 1 人 1 鬼、2 人或 2 鬼,且船需要人或鬼划船才能往返;要求无论在哪一岸,人的数量都不能少于鬼的数量(否则人会被鬼吃掉),需找到安全将所有人和鬼送到对岸的方案。

通过分阶段的往返摆渡实现安全渡河:先分两次将 2 个鬼送到对岸并留 1 鬼在对岸、1 鬼返回,再让 2 人过河后 1 人 1 鬼返回,接着让剩余 2 人过河后 1 鬼返回,最后分两次将剩余 2 个鬼全部送到对岸,全程保证每一步两岸的人数都不小于鬼数,最终安全完成全员渡河。

赛马问题

第一题是有 25 匹马、5 条跑道,无法计时,每次只能让 5 匹马同时比赛,需要找出其中速度最快的 3 匹马;第二题是有 64 匹马、8 条跑道,无法计时,每次只能让 8 匹马同时比赛,需要找出其中速度最快的 4 匹马;第三题是有 25 匹马、5 条跑道,无法计时,每次只能让 5 匹马同时比赛,需要找出其中速度最快的 5 匹马。

针对第一题 25 匹马 5 条跑道找最快 3 匹,最优方案共需 7 次比赛:先将 25 匹马分为 5 组,每组 5 匹,进行 5 次分组赛,淘汰每组排名 4、5 的马匹;再让 5 个组的第 1 名进行第 6 次比赛,确定全局最快的马,同时根据这次比赛的结果淘汰不可能进入前 3 的马匹,最终只留下 5 匹有竞争力的候选马,进行第 7 次比赛,决出第 2、3 名,全程共 7 次。针对第二题 64 匹马 8 条跑道找最快 4 匹,最优方案共需 11 次比赛:先将 64 匹马分为 8 组,每组 8 匹,进行 8 次分组赛,淘汰每组排名 5-8 的马匹;再让 8 个组的第 1 名进行第 9 次比赛,确定全局最快的马,同时根据这次比赛的结果淘汰不可能进入前 4 的马匹,最终筛选出 9 匹有竞争力的候选马,分两次比赛(第 10、11 次)决出剩余的 3 个名次,全程共 11 次。针对第三题 25 匹马 5 条跑道找最快 5 匹,最少需要 8 次、最多需要 9 次比赛:先进行 5 次分组赛、1 次各组头名赛(共 6 次)确定全局第 1 名,再根据头名赛结果筛选出 10 匹有竞争力的候选马,进行第 7 次比赛确定第 2、3 名,同时进一步筛选候选,第 8 次比赛即可决出第 4、5 名,若出现特殊情况则需要第 9 次比赛补赛,因此最少 8 次、最多 9 次。

给定随机函数生成其他的随机函数

给定一个能等概率生成 1 到 5 这五个整数的随机函数 Rand5 (),要求基于该函数设计一个新的随机函数 Rand7 (),使其能等概率生成 1 到 7 这七个整数,且需遵循随机数生成的基本逻辑,不能引入额外的外部随机源,核心在于利用 Rand5 () 构造出足够大且均匀的随机空间,再通过筛选和映射实现目标范围的均匀随机数生成。

解决该问题的核心方法是拒绝采样法 ,具体实现步骤如下:首先,利用两次 Rand5 () 构造出 1 到 25 的均匀随机数,具体公式为 num = 5 * (Rand5() - 1) + Rand5(),其中 Rand5 ()-1 会生成 0、1、2、3、4,乘以 5 后得到 0、5、10、15、20,再加上 Rand5 () 生成的 1-5,最终得到 1-25 共 25 个整数,且每个数被生成的概率均为 1/25,保证了基础空间的均匀性;其次,由于 25 大于 7,我们选取 1 到 21 这个区间(21 是小于等于 25 的 7 的最大整数倍),若生成的 num 大于 21(即 22、23、24、25),则直接丢弃该结果并重新生成,通过拒绝采样保证剩余样本的均匀性;最后,对 1 到 21 范围内的 num 进行映射,公式为 (num - 1) % 7 + 1,该映射可将 1-21 等概率划分为 3 组 1-7,从而等概率生成 1-7 的随机数,最终实现的 Rand7 () 函数代码逻辑为:通过循环执行上述构造、筛选和映射步骤,直到生成有效结果,返回映射后的数值,全程共需利用 Rand5 () 生成平均约 25/21 次即可得到 1 个 Rand7 () 的结果,确保了 1-7 每个数的生成概率均为 1/7,满足题目要求。

具体来说,其核心思路就是先构造一个足够大且概率完全均匀的随机空间,然后在里面取一段能被目标范围整除的区间做等概率映射,超出区间的结果直接丢弃,最终就能得到目标范围的等概率随机数。

砝码称重问题

有 9 个外观完全相同的砝码,其中 8 个重量一致,仅 1 个砝码比其他砝码更轻,现有一个无砝码的天平,要求用最少的称重次数,找出这个重量偏轻的砝码。

至少需要称重 2 次即可找出轻砝码,具体方法为:第一次将 9 个砝码平均分成 3 组,每组 3 个,把其中两组放在天平两端称重,若天平某一端更轻,则轻砝码在该组中,若天平平衡,则轻砝码在未称重的第三组中;第二次从包含轻砝码的 3 个砝码中任选 2 个放在天平两端称重,若某一端更轻,则该端砝码为目标轻砝码,若天平平衡,则未称重的那个砝码就是偏轻的砝码,全程仅需 2 次称重即可保证找出轻砝码。

其核心思想就是利用三分法将问题规模每次缩小为原来的 1/3,通过两次天平称重逐步排除不可能的砝码,最终定位出唯一的轻砝码,用最少的称重次数实现最优查找。

空瓶问题

有 1000 瓶饮料,每 3 个空瓶可兑换 1 瓶饮料,喝完饮料后会产生新的空瓶,问通过不断用空瓶兑换,最终最多能喝到多少瓶饮料。

最多能喝到 1499 瓶饮料,核心计算逻辑为:先喝掉初始的 1000 瓶得到 1000 个空瓶;后续每 3 个空瓶换 1 瓶饮料,喝完的空瓶继续参与兑换,直到剩余空瓶数不足 3 个无法再换;经计算,总兑换次数为 499 次,最终总饮用数量为初始 1000 瓶加上兑换的 499 瓶,合计 1499 瓶。

该问题的数学计算核心在于将 "3 个空瓶换 1 瓶饮料" 的规则转化为2 个空瓶对应 1 瓶纯饮料的等价关系,通过公式 总饮用瓶数=初始瓶数+⌊3−1初始瓶数−1​⌋ 进行精确求解;代入初始 1000 瓶计算时,先计算 ⌊3−11000−1​⌋=⌊2999​⌋=499,即总共能额外兑换 499 瓶饮料,再加上最初的 1000 瓶,最终合计得出最多能喝到 1499 瓶饮料,其中 499 即为通过空瓶循环兑换出的饮料总次数。

毒药毒老鼠问题

有 1000 个外观完全相同的瓶子,其中 999 瓶为普通清水,仅 1 瓶含剧毒;任何喝下毒药的生命都会在一周后死亡,而你仅有 10 只小白鼠和 1 周的时间,需要设计一种方法,精准确定出唯一的那瓶毒药。

核心解法为二进制编码法,具体操作如下:首先将 1000 个瓶子依次编号为 1 至 1000,同时将 10 只小白鼠编号为 0 至 9(对应二进制位的权重);接着把每个瓶子的编号转换为 10 位二进制数(不足 10 位补前导 0),对于每一瓶水,若其二进制编码的某一位为 1,就给对应编号的小白鼠喂该瓶水;一周后观察小白鼠的存活状态,死亡的小白鼠对应二进制位记为 1,存活则记为 0,最终将得到的 10 位二进制数转换为十进制数,该数值即为毒药瓶子的编号。原理在于 10 位二进制可表示1024种状态,完全覆盖 1000 个瓶子的编号需求,通过小白鼠的生死状态唯一锁定毒药位置。

我们用十位二进制来表示这些药水的编号,然后把十只老鼠对应这十个位,每瓶药的十位二进制表示中那个位为1就给对应位的老鼠喝药,这样一周后所有死的老鼠对应的位都是1剩下的都是0的药水编号就是毒药。

烧绳计时问题

现有若干根不均匀的绳子,每根绳子从一端烧到另一端的总时长均为 1 小时(60 分钟),但绳子各段燃烧速度完全不均匀,无法通过对折等方式估算时间,要求利用这些绳子,分别准确计时 15 分钟、30 分钟、45 分钟、75 分钟等指定时长。

利用两端同时燃烧使时长减半的核心逻辑,通过多根绳子的接力式点火,组合出 15 分钟为基础单位的任意时长,完全规避绳子不均匀的影响,实现精准计时。

取 1 根绳子同时点燃两端,烧尽时即计时 30 分钟;取 2 根绳子 A、B,先同时点燃 A 的两端和 B 的一端,A 烧尽(30 分钟)时点燃 B 的另一端,B 烧尽的剩余过程即为 15 分钟;在此基础上,等 B 完全烧尽后总时长恰好为 45 分钟;若取 3 根绳子 A、B、C,在 45 分钟的节点立即点燃 C 的两端,待 C 烧尽后总时长即可达到 75 分钟,由此可通过不同绳子的组合燃烧方式精准实现 15、30、45、75 分钟的计时。

时针重合问题

在 24 小时的时间周期内,钟表的时针、分针、秒针三针完全重合的次数是多少。

我们先计算时针、分针、秒针的角速度:时针为 0.5°/ 分钟,分针为 6°/ 分钟,秒针为 360°/ 分钟;先推导时针与分针的重合规律,得出 12 小时内二者重合 11 次、24 小时内共 22 次,再逐一验证这些重合时刻秒针的位置,发现仅在 0 点(24 点)和 12 点整时,三针的角度同时为 0°,其余时刻秒针均无法与时针、分针同步,因此 24 小时内三针完全重合仅 2 次。

奴隶猜帽子问题

100 个奴隶站成一纵列,每人头上随机戴黑色或白色帽子,自己看不到帽子颜色,但能看见前面所有人的帽子颜色;从最后一个奴隶开始,每人只能用同一声调说 "黑" 或 "白",说对自己帽子颜色就存活,说错就被处决,所有人都能听见前面的发言,且提前可以商量策略,求 100 人在足够聪明的前提下,最大存活率是多少。

利用最后一个奴隶的发言传递黑帽子总数的奇偶校验信息,让前面 99 个奴隶通过已知的前面帽子颜色 + 后面的正确发言,依次推算出自己的帽子颜色,实现 99 人 100% 存活、最后 1 人 50% 存活的最大存活率。

奴隶们提前约定 "黑" 代表奇数个黑帽、"白" 代表偶数个黑帽,最后一个奴隶通过数前方 99 人黑帽数量的奇偶性说出对应颜色,虽有 50% 概率存活但传递了全局奇偶信息;第 99 人结合前方 98 人黑帽奇偶性与全局奇偶性就能算出自身颜色并 100% 存活,后续每个奴隶依次依据前方帽子情况、已确定的他人颜色和初始奇偶性推算,从第 98 人开始所有人都能 100% 存活,最终实现 99 人必定存活、最后 1 人 50% 存活的最大存活率。

小猴子搬香蕉问题

小猴子有 100 根香蕉,家在 50 米外,每次最多只能搬 50 根香蕉(多了会被压死),每走 1 米就要吃掉 1 根香蕉,问最多能把多少根香蕉搬回家。

小猴子先分两次将香蕉搬运到 16 米处的中转点,消耗 48 根香蕉后还剩52根,再从中转点搬 50 根走完剩余 34 米,消耗 34 根,最终最多能把 16 根香蕉搬回家。

高楼扔鸡蛋问题

对于 2 个鸡蛋测试 100 层楼鸡蛋不会摔碎的临界点这一经典问题,最优策略下最少需要 14 次尝试即可保证测出临界点,这是该问题的最小最大尝试次数,具体采用等差数列分段法,核心逻辑是让每次尝试的最坏情况尝试次数保持一致,假设最少需要 x 次尝试,第一次从第 x 层扔鸡蛋,若鸡蛋碎了,就用剩余 x-1 次机会从 1 到 x-1 层依次测试,刚好覆盖 x-1 层,若鸡蛋没碎,第二次就跳过 x-1 层,从第 x+(x-1) 层扔,保证剩余 x-2 次能覆盖中间 x-2 层,以此类推,所有分段的楼层数之和需满足等差数列求和公式2x(x+1)​≥100,经计算当 x=13 时和为 91 不足 100,x=14 时和为 105 满足要求,因此确定最少 14 次,实际操作中第一次在 14 层扔,若碎了就从 1 到 13 层依次试,若没碎第二次在 27 层扔,碎了就从 15 到 26 层试,后续每次跳跃的层数递减 1,依次类推,最终覆盖 100 层,确保最坏情况下最多 14 次就能找到鸡蛋不会摔碎的临界点。

蚂蚁爬树问题

在长度为 M 的树枝上放置 N 只速度相同的蚂蚁,蚂蚁在树枝上行走时若与其他蚂蚁相遇,会各自向反方向折返,要求计算所有蚂蚁都爬下树枝的总爬行距离,或是全部蚂蚁都爬下树枝所需的总时间。

解答该问题的核心是利用 "蚂蚁碰撞折返等价于互相穿过、身份互换" 的等效思想,将复杂的碰撞过程简化为所有蚂蚁互不干扰、沿原方向直行的理想情况,因此所有蚂蚁的总爬行距离等于每只蚂蚁从初始位置径直爬下树枝的路程之和,全部蚂蚁爬下的总时间则等于离端点最远的蚂蚁爬完全程所需的时间(即树枝长度 M 除以蚂蚁爬行速度 v),与蚂蚁的数量 N 无关。

海盗分金币问题

5 个海盗抢到 100 枚价值相同的金币,抽签确定 1 到 5 号的顺序,由 1 号先提出分配方案,5 人表决,需超过半数同意才按方案分配,否则 1 号被扔入海;若 1 号死亡则由 2 号提方案,4 人表决,同样需超半数同意,否则 2 号被扔入海,以此类推;所有海盗都足够聪明、利益至上,在保命的前提下会尽可能多拿金币,问题是 1 号海盗如何分配才能让自己拿到最多金币。

采用逆推法从最终状态分析,仅存 5 号时独吞 100 枚;仅存 4、5 号时 4 号必死、5 号拿 100;仅存 3、4、5 号时 3 号给 4 号 0 枚、5 号 0 枚,靠 4 号保命的需求获得支持,拿 100 枚;仅存 2、3、4、5 号时 2 号给 4、5 各 1 枚,获得支持拿 98 枚;因此 1 号只需给 3 号 1 枚、给 4 号或 5 号其中 1 人 2 枚,用最小成本收买 3 号和 4 号 / 5 号,加上自己的票凑够超半数,最终 1 号最多可拿 97 枚金币,分配方案为 1 号 97 枚、2 号 0 枚、3 号 1 枚、4 号 2 枚、5 号 0 枚(或 1 号 97 枚、2 号 0 枚、3 号 1 枚、4 号 0 枚、5 号 2 枚)。

火枪手决斗问题

甲、乙、丙三个火枪手彼此痛恨,准备进行决斗,其中甲的枪法最好,十发八中(命中率 80%),乙次之,十发六中(命中率 60%),丙的枪法最差,十发四中(命中率 40%);规则为三人同时开枪,每轮每人只能开一枪,且每个枪手都足够理性、以存活为第一目标,会优先射击对自己威胁最大的对手,问题是枪战后谁活下来的概率更大。

通过分析三人的最优策略(甲优先射击威胁最大的乙,乙优先射击威胁最大的甲,丙优先射击威胁最大的甲),结合概率计算,最终丙的存活概率最高,约为 69.1%,甲的存活概率约为 11.0%,乙的存活概率约为 7.6%,还有约 12.3% 的概率三人全部死亡;核心逻辑是枪法最差的丙成为了另外两个强敌的优先攻击对象的旁观者,在第一轮就有极高概率让甲和乙互相击杀,从而以弱胜强,获得远高于另外两人的存活机会。

先手必胜问题

共有 100 本书,两人轮流拿书,每人每次必须拿 1 至 5 本,目标是迫使对方拿最后一本书,即自己拿到第 100 本书,需要找到一种拿书策略来保证实现这一目标。

由于每次可以拿 1-5 本,关键在于控制每轮两人拿书总数为6 本 (1+5或2+4或3+3),因为100刚好是6的倍数(100÷6=16 余 4),所以先手应先拿4 本,之后无论对方拿n本(1≤n≤5),先手都拿 6−n本,这样每轮都会消耗 6 本,经过 16 轮后刚好拿完第 100 本,从而保证最后一次是自己拿。

相关推荐
卷心菜不卷Iris9 个月前
第4章唯一ID生成器——4.1 分布式唯一ID
java·分布式·系统设计·场景题·分布式唯一id
Jesslili1 年前
如何高效的处理海量数据?
面试·海量数据·场景题
xiao--xin1 年前
Java定时任务实现方案(四)——Spring Task
java·笔记·后端·spring·定时任务·场景题
绝命Coding2 年前
大厂面试官问我:两个1亿行的文件怎么求交集?【后端八股文十五:场景题合集】
java·开发语言·后端·面试·求职招聘·场景题