Please enable Javascript to view the contents

🔥小学二年级数学题,李永乐居然做不出来!程序员给出通解 💯

 ·  ☕ 9 分钟

小学二年级数学题,李永乐居然做不出来

前段时间,李永乐老师发布视频小学二年级数学题,李永乐居然做不出来!- 西瓜视频,给大家讲解了一道小学二年级趣味数学题。

“李永乐居然做不出来!”是李永乐老师谦虚的说法。李永乐老师不仅解了出来,还从小问题、特殊的问题出发,使用图论+反证法严密论证给出了通解,让大家感受到了数学的魅力。

这道题也引起了大家的兴趣,我们码农读书交流群里的程序员们也纷纷给出解法。我也蹭一下李永乐老师的热度,写了个JS小脚本,用于模拟整个比赛过程,方便大家解答此类题目。

小学二年级数学题

小学二年级数学题

有这样一个小学二年级数学题:9辆赛车速度各不相同,它们要比快慢,但没有计时工具,只能在赛道上比谁先谁后,而且每次最多只能有3辆车比赛。那么,最少比几次,能保证选出最快的2辆赛车?

程序模拟

模拟思路

  • 随机构建比赛选手,用数组记录各选手速度
  • 分组比赛,让所有选手参与比赛
  • 每场比赛结束后,提取最快的2名(奖牌数量)选手,并记录比赛结果
  • 每回合比赛结束后,检查比赛结果
    • 如果选手大于赛道数量(也必大于奖牌数量),重新分组比赛
    • 如果参赛选手数量小于或等于奖牌数,触发排名机制
  • 获奖人数等于奖牌数量,比赛结束

模拟脚本

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// 🚗 参数选手数量
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场。

参赛选手9名、赛道3条、奖牌2位

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
参赛选手: [
   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场比赛。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
参赛选手: [
  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场比赛。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
参赛选手: [
  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匹马,最少要几次呢?

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
参赛选手: [
  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场。

欢迎大家执行脚本验证。

分享

码中人
作者
码中人
Web Developer