小学二年级数学题,李永乐居然做不出来!程序员给出通解
前段时间,李永乐老师发布视频小学二年级数学题,李永乐居然做不出来!- 西瓜视频,给大家讲解了一道小学二年级趣味数学题。
• 小学二年级数学题,李永乐居然做不出来!- 西瓜视频
• 小学二年级数学题,李永乐居然做不出来 - 搜狐
• 小学二年级数学题,震惊了~
“李永乐居然做不出来!”是李永乐老师谦虚的说法。李永乐老师不仅解了出来,还从小问题、特殊的问题出发,使用图论+反证法严密论证给出了通解,让大家感受到了数学的魅力。
这道题也引起了大家的兴趣,我们码农读书交流群里的程序员们也纷纷给出解法。我也蹭一下李永乐老师的热度,写了个JS小脚本,用于模拟整个比赛过程,方便大家解答此类题目。
小学二年级数学题
有这样一个小学二年级数学题:9辆赛车速度各不相同,它们要比快慢,但没有计时工具,只能在赛道上比谁先谁后,而且每次最多只能有3辆车比赛。那么,最少比几次,能保证选出最快的2辆赛车?
程序模拟
模拟思路
• 随机构建比赛选手,用数组记录各选手速度
• 分组比赛,让所有选手参与比赛
• 每场比赛结束后,提取最快的2名(奖牌数量)选手,并记录比赛结果
• 每回合比赛结束后,检查比赛结果
• 如果选手大于赛道数量(也必大于奖牌数量),重新分组比赛
• 如果参赛选手数量小于或等于奖牌数,触发排名机制
• 获奖人数等于奖牌数量,比赛结束
模拟脚本
// 🚗 参数选手数量
const PLAYERS_NUM = 9;
// 🛣️ 赛道数量
const RACEWAY_SIZE = 3;
// 🏆 奖牌数量
const WINNERS_NUM = 2;
// 备注:以下脚本需满足 RACEWAY_SIZE > WINNERS_NUM
// 随机生成参赛选手
const PLAYERS = makePlayers(PLAYERS_NUM);
console.log("参赛选手:", PLAYERS)
const winners = [...PLAYERS].sort(sort).slice(0, WINNERS_NUM);
console.log("应获奖选手:", winners);
console.log("==== 过程检查 ====")
race(PLAYERS);
// 比赛
function race(players, round_num = 0, race_time = 0, winners = []) {
// 比赛回合
round_num += 1;
let round_result = null;
console.log(`第 ${round_num} 轮比赛开始 🏁,参赛选手为:`, players);
// 选手大于赛道数,分组比赛,否则直接比赛
if (players.length > RACEWAY_SIZE) {
const groups = grouping(players, RACEWAY_SIZE);
round_result = groups.map((group) => {
if (Array.isArray(group) && group.length == RACEWAY_SIZE) {
// 比赛场次加1
race_time += 1;
return group.sort(sort).slice(0, WINNERS_NUM - winners.length)
} else {
return group;
}
});
// 因为用嵌套数组模拟分组情况,打平一级以修正数据
if (getArrayDepth(round_result) == 3) {
round_result = round_result.flat(1);
}
} else {
round_result = players.sort(sort).slice(0, WINNERS_NUM - winners.length);
// 比赛场次加1
race_time += 1;
}
console.log(`第 ${round_num} 轮比赛结束,比赛结果为:`, round_result);
if (round_result.length <= WINNERS_NUM) {
console.log('==========触发排名===========');
if (getArrayDepth(round_result) > 1) {
round_result = round_result.map((player, i) => {
if (i == 0) {
if (Array.isArray(player)) {
// 排名第一小组的第一名,直接获得奖牌 🥇
winners.push(player.shift())
return player.slice(0, WINNERS_NUM - winners.length)
} else {
winners.push(player);
return [];
}
}
else {
return Array.isArray(player) ? player.slice(0, WINNERS_NUM - winners.length) : player;
}
})
round_result = round_result.flat(1);
} else {
winners.push(...round_result.slice(0, WINNERS_NUM - winners.length));
}
}
const ranked_players = getNextRoundPlayers(round_result, RACEWAY_SIZE);
console.log(`第 ${round_num} 轮比赛晋级选手 🚗,`, ranked_players, `总共进行了 ${race_time} 场比赛;`, '获奖选手为 🏆:', winners);
console.log('=========================================================')
// 眺出递归条件
if (winners.length < WINNERS_NUM) {
race(ranked_players, round_num, race_time, winners);
} else {
console.log("比赛结束")
return;
}
}
function getNextRoundPlayers(round_result, length) {
if (round_result.flat().length <= length) {
return round_result.flat()
}
const currentArrayDepth = getArrayDepth(round_result);
if (currentArrayDepth > 2) {
round_result = round_result.flat(currentArrayDepth - 1);
}
return round_result;
}
function makePlayers(length, max = length * 3, min = 5) {
let players = new Set();
while (players.size < length) {
let player = Math.floor(Math.random() * max);
if (player >= min) {
players.add(player);
}
}
return [...players];
}
// 分组
function grouping(players, group_size) {
const groups = [];
const mod = players.length % group_size;
const grouped_players = players.slice(0, players.length - mod);
for (let index = 0; index < grouped_players.length; index += group_size) {
const group = grouped_players.slice(index, index + group_size);
groups.push(group);
}
if (mod > 0) {
groups.push(...players.slice(-mod));
}
console.log("分组情况🎏",groups);
return groups;
}
// 一场比赛(即排序)
function sort(a, b) {
a = Array.isArray(a) ? a[0] : a;
b = Array.isArray(b) ? b[0] : b;
return b - a;
}
// 获取数组深度
// 因为用嵌套数组模拟分组情况,需要获取数组深度
function getArrayDepth(value) {
return Array.isArray(value) ?
1 + Math.max(0, ...value.map(getArrayDepth)) :
0;
}
程序验证
9-3-2
首先是参赛选手9名、赛道3条、奖牌2位的情况,其结果为需要赛5场。
参赛选手: [
7, 10, 25, 17, 20,
11, 6, 26, 8
]
应获奖选手: [ 26, 25 ]
==== 过程检查 ====
第 1 轮比赛开始 🏁,参赛选手为: [
7, 10, 25, 17, 20,
11, 6, 26, 8
]
分组情况🎏 [ [ 7, 10, 25 ], [ 17, 20, 11 ], [ 6, 26, 8 ] ]
第 1 轮比赛结束,比赛结果为: [ [ 25, 10 ], [ 20, 17 ], [ 26, 8 ] ]
第 1 轮比赛晋级选手 🚗, [ [ 25, 10 ], [ 20, 17 ], [ 26, 8 ] ] 总共进行了 3 场比赛; 获奖选手为 🏆: []
=========================================================
第 2 轮比赛开始 🏁,参赛选手为: [ [ 25, 10 ], [ 20, 17 ], [ 26, 8 ] ]
第 2 轮比赛结束,比赛结果为: [ [ 26, 8 ], [ 25, 10 ] ]
==========触发排名===========
第 2 轮比赛晋级选手 🚗, [ 8, 25 ] 总共进行了 4 场比赛; 获奖选手为 🏆: [ 26 ]
=========================================================
第 3 轮比赛开始 🏁,参赛选手为: [ 8, 25 ]
第 3 轮比赛结束,比赛结果为: [ 25 ]
==========触发排名===========
第 3 轮比赛晋级选手 🚗, [ 25 ] 总共进行了 5 场比赛; 获奖选手为 🏆: [ 26, 25 ]
=========================================================
比赛结束
10-3-2
也适用于参赛选手10名、赛道3条、奖牌2位的情况,其结果为最少需要6场比赛。
参赛选手: [
13, 5, 16, 23, 17,
9, 27, 14, 8, 25
]
应获奖选手: [ 27, 25 ]
==== 过程检查 ====
第 1 轮比赛开始 🏁,参赛选手为: [
13, 5, 16, 23, 17,
9, 27, 14, 8, 25
]
分组情况🎏 [ [ 13, 5, 16 ], [ 23, 17, 9 ], [ 27, 14, 8 ], 25 ]
第 1 轮比赛结束,比赛结果为: [ [ 16, 13 ], [ 23, 17 ], [ 27, 14 ], 25 ]
第 1 轮比赛晋级选手 🚗, [ [ 16, 13 ], [ 23, 17 ], [ 27, 14 ], 25 ] 总共进行了 3 场比赛; 获奖选手为 🏆: []
=========================================================
第 2 轮比赛开始 🏁,参赛选手为: [ [ 16, 13 ], [ 23, 17 ], [ 27, 14 ], 25 ]
分组情况🎏 [ [ [ 16, 13 ], [ 23, 17 ], [ 27, 14 ] ], 25 ]
第 2 轮比赛结束,比赛结果为: [ [ 27, 14 ], [ 23, 17 ], 25 ]
第 2 轮比赛晋级选手 🚗, [ [ 27, 14 ], [ 23, 17 ], 25 ] 总共进行了 4 场比赛; 获奖选手为 🏆: []
=========================================================
第 3 轮比赛开始 🏁,参赛选手为: [ [ 27, 14 ], [ 23, 17 ], 25 ]
第 3 轮比赛结束,比赛结果为: [ [ 27, 14 ], 25 ]
==========触发排名===========
第 3 轮比赛晋级选手 🚗, [ 14, 25 ] 总共进行了 5 场比赛; 获奖选手为 🏆: [ 27 ]
=========================================================
第 4 轮比赛开始 🏁,参赛选手为: [ 14, 25 ]
第 4 轮比赛结束,比赛结果为: [ 25 ]
==========触发排名===========
第 4 轮比赛晋级选手 🚗, [ 25 ] 总共进行了 6 场比赛; 获奖选手为 🏆: [ 27, 25 ]
=========================================================
比赛结束
11-3-2
也适用于参赛选手11名、赛道3条、奖牌2位的情况,其结果为最少需要7场比赛。
参赛选手: [
13, 5, 10, 18, 11,
26, 14, 25, 28, 15,
27
]
应获奖选手: [ 28, 27 ]
==== 过程检查 ====
第 1 轮比赛开始 🏁,参赛选手为: [
13, 5, 10, 18, 11,
26, 14, 25, 28, 15,
27
]
分组情况🎏 [ [ 13, 5, 10 ], [ 18, 11, 26 ], [ 14, 25, 28 ], 15, 27 ]
第 1 轮比赛结束,比赛结果为: [ [ 13, 10 ], [ 26, 18 ], [ 28, 25 ], 15, 27 ]
第 1 轮比赛晋级选手 🚗, [ [ 13, 10 ], [ 26, 18 ], [ 28, 25 ], 15, 27 ] 总共进行了 3 场比赛; 获奖选手为 🏆: []
=========================================================
第 2 轮比赛开始 🏁,参赛选手为: [ [ 13, 10 ], [ 26, 18 ], [ 28, 25 ], 15, 27 ]
分组情况🎏 [ [ [ 13, 10 ], [ 26, 18 ], [ 28, 25 ] ], 15, 27 ]
第 2 轮比赛结束,比赛结果为: [ [ 28, 25 ], [ 26, 18 ], 15, 27 ]
第 2 轮比赛晋级选手 🚗, [ [ 28, 25 ], [ 26, 18 ], 15, 27 ] 总共进行了 4 场比赛; 获奖选手为 🏆: []
=========================================================
第 3 轮比赛开始 🏁,参赛选手为: [ [ 28, 25 ], [ 26, 18 ], 15, 27 ]
分组情况🎏 [ [ [ 28, 25 ], [ 26, 18 ], 15 ], 27 ]
第 3 轮比赛结束,比赛结果为: [ [ 28, 25 ], [ 26, 18 ], 27 ]
第 3 轮比赛晋级选手 🚗, [ [ 28, 25 ], [ 26, 18 ], 27 ] 总共进行了 5 场比赛; 获奖选手为 🏆: []
=========================================================
第 4 轮比赛开始 🏁,参赛选手为: [ [ 28, 25 ], [ 26, 18 ], 27 ]
第 4 轮比赛结束,比赛结果为: [ [ 28, 25 ], 27 ]
==========触发排名===========
第 4 轮比赛晋级选手 🚗, [ 25, 27 ] 总共进行了 6 场比赛; 获奖选手为 🏆: [ 28 ]
=========================================================
第 5 轮比赛开始 🏁,参赛选手为: [ 25, 27 ]
第 5 轮比赛结束,比赛结果为: [ 27 ]
==========触发排名===========
第 5 轮比赛晋级选手 🚗, [ 27 ] 总共进行了 7 场比赛; 获奖选手为 🏆: [ 28, 27 ]
=========================================================
比赛结束
64-8-4
同样,类似的题目都可以解。
有64匹马,8条赛道,要找出最快的4匹马,最少要几次呢?
参赛选手: [
130, 56, 21, 13, 171, 181, 49, 5, 93, 150, 54,
90, 112, 68, 43, 94, 180, 125, 102, 135, 58, 76,
46, 42, 83, 107, 57, 129, 64, 155, 25, 22, 122,
73, 136, 85, 27, 26, 9, 144, 159, 71, 127, 16,
190, 31, 191, 158, 167, 45, 20, 147, 164, 77, 14,
151, 143, 177, 23, 36, 132, 138, 78, 19
]
应获奖选手: [ 191, 190, 181, 180 ]
==== 过程检查 ====
第 1 轮比赛开始 🏁,参赛选手为: [
130, 56, 21, 13, 171, 181, 49, 5, 93, 150, 54,
90, 112, 68, 43, 94, 180, 125, 102, 135, 58, 76,
46, 42, 83, 107, 57, 129, 64, 155, 25, 22, 122,
73, 136, 85, 27, 26, 9, 144, 159, 71, 127, 16,
190, 31, 191, 158, 167, 45, 20, 147, 164, 77, 14,
151, 143, 177, 23, 36, 132, 138, 78, 19
]
分组情况🎏 [
[
130, 56, 21, 13,
171, 181, 49, 5
],
[
93, 150, 54, 90,
112, 68, 43, 94
],
[
180, 125, 102, 135,
58, 76, 46, 42
],
[
83, 107, 57, 129,
64, 155, 25, 22
],
[
122, 73, 136, 85,
27, 26, 9, 144
],
[
159, 71, 127, 16,
190, 31, 191, 158
],
[
167, 45, 20, 147,
164, 77, 14, 151
],
[
143, 177, 23, 36,
132, 138, 78, 19
]
]
第 1 轮比赛结束,比赛结果为: [
[ 181, 171, 130, 56 ],
[ 150, 112, 94, 93 ],
[ 180, 135, 125, 102 ],
[ 155, 129, 107, 83 ],
[ 144, 136, 122, 85 ],
[ 191, 190, 159, 158 ],
[ 167, 164, 151, 147 ],
[ 177, 143, 138, 132 ]
]
第 1 轮比赛晋级选手 🚗, [
[ 181, 171, 130, 56 ],
[ 150, 112, 94, 93 ],
[ 180, 135, 125, 102 ],
[ 155, 129, 107, 83 ],
[ 144, 136, 122, 85 ],
[ 191, 190, 159, 158 ],
[ 167, 164, 151, 147 ],
[ 177, 143, 138, 132 ]
] 总共进行了 8 场比赛; 获奖选手为 🏆: []
=========================================================
第 2 轮比赛开始 🏁,参赛选手为: [
[ 181, 171, 130, 56 ],
[ 150, 112, 94, 93 ],
[ 180, 135, 125, 102 ],
[ 155, 129, 107, 83 ],
[ 144, 136, 122, 85 ],
[ 191, 190, 159, 158 ],
[ 167, 164, 151, 147 ],
[ 177, 143, 138, 132 ]
]
第 2 轮比赛结束,比赛结果为: [
[ 191, 190, 159, 158 ],
[ 181, 171, 130, 56 ],
[ 180, 135, 125, 102 ],
[ 177, 143, 138, 132 ]
]
==========触发排名===========
第 2 轮比赛晋级选手 🚗, [
190, 159, 158, 181,
171, 130, 180, 135,
125, 177, 143, 138
] 总共进行了 9 场比赛; 获奖选手为 🏆: [ 191 ]
=========================================================
第 3 轮比赛开始 🏁,参赛选手为: [
190, 159, 158, 181,
171, 130, 180, 135,
125, 177, 143, 138
]
分组情况🎏 [
[
190, 159, 158,
181, 171, 130,
180, 135
],
125,
177,
143,
138
]
第 3 轮比赛结束,比赛结果为: [ [ 190, 181, 180 ], 125, 177, 143, 138 ]
第 3 轮比赛晋级选手 🚗, [
190, 181, 180,
125, 177, 143,
138
] 总共进行了 10 场比赛; 获奖选手为 🏆: [ 191 ]
=========================================================
第 4 轮比赛开始 🏁,参赛选手为: [
190, 181, 180,
125, 177, 143,
138
]
第 4 轮比赛结束,比赛结果为: [ 190, 181, 180 ]
==========触发排名===========
第 4 轮比赛晋级选手 🚗, [ 190, 181, 180 ] 总共进行了 11 场比赛; 获奖选手为 🏆: [ 191, 190, 181, 180 ]
=========================================================
比赛结束
答案是11场。
欢迎大家执行脚本验证。
往期推荐
• 吴军老师作品集
欢迎关注我的公众号“码中人”,原创技术文章第一时间推送。