说,我们有100多名参赛者和3个获奖名额。我需要安排尽可能少的比赛才能找到3名获胜者。其他地方根本不重要。 循环算法看起来不必要昂贵。
这是我的解决方案:
const match = (a, b) => {
if (!a || !b) {
return {winner: a || b}
}
// simulate match
const winner = Math.random() > 0.5 ? a : b
console.log(`Match between ${a} and ${b}: ${winner} wins`)
return {winner, looser: winner === a ? b : a}
}
let participants = {
// [id]: {win: Number, loose: Number}
}
let participantsNumber = 100
let n = 0
// create random participants
while(n < participantsNumber) {
n++
participants[String(n)] = {win: 0, loose: 0}
}
let round = 0
while(participantsNumber > 3) {
let odd = true
let matches = []
_.map(participants, (winLooseStats, id) => {
if (odd) {
odd = false
matches.push({player_1: id})
} else {
odd = true
let opponentFound = false
matches.map(match => {
if (!match.player_2 && !opponentFound) {
opponentFound = true
match.player_2 = id
}
})
}
})
console.log('matches', matches)
// run matches
matches.forEach(({player_1, player_2}) => {
const {winner, looser} = match(player_1, player_2)
participants[winner].win++
if (looser) {
participants[looser].loose++
}
})
// remove those, who has lost 3 times
_.map(participants, ({win, loose}, id) => {
if (loose > 2) {
console.log(`Player ${id} has lose 3 times`)
delete participants[id]
participantsNumber--
}
})
round++
console.log(`Round ${round} complete. ${participantsNumber} players left`)
}
console.log(`3 champions: ${_.map(participants, (wl, id) => id).join(', ')}`)
每100名参与者约12轮。是否可以减少轮数?
答案 0 :(得分:0)
问题有点模糊,但我认为你的规则如下:
假设这是正确的,并且您有n
个玩家,那么您可以使用标准single elimination tournament以最佳方式解决此问题,以找到获胜者和第二名。要找到第三名,你必须在两个没有进入最后一场比赛的人之间再添一场比赛。