You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何对格斗场次计算的Backward recursion递归函数做反向求解

逆运算实现思路

原正向计算函数qwe(n)是严格递增函数,所有初始人数n都可以拆成 n = k * 2^m(k为奇数,m为非负整数),对应总场次公式展开为:

s = k*(2^m -1) + k*(k-1)/2

基于这个规律可以通过两种方式实现逆运算,以下是可直接运行的JS实现:


方式1:枚举法(逻辑最简单,不易出错)

利用正向函数单调递增的特性,从小到大遍历可能的初始人数,直到计算出的总场次匹配目标值即可。

// 原正向计算函数
function qwe(number) {
  if(number % 2) {
    return number * (number - 1) / 2
  } else {
    const half = number / 2; 
    return half + qwe(half)
  }
}

// 逆运算:输入总场次s,返回所有符合的初始人数数组
function reverseQwe(s) {
  const solutions = []
  let n = 1
  while(true) {
    const current = qwe(n)
    if(current === s) solutions.push(n)
    if(current > s) break
    n++
  }
  return solutions
}

// 测试用例
console.log(reverseQwe(3)) // 输出 [3,4] 两个解
console.log(reverseQwe(6)) // 输出 [6]
console.log(reverseQwe(10)) // 输出 [5]

方式2:递归法(效率更高,无需重复计算正向值)

直接基于推导的公式递归查找所有符合条件的k和m组合:

function reverseQweRecursive(s, multiple = 1, solutions = []) {
  // 校验当前s是否对应奇数k的单循环场次
  const discriminant = 1 + 8 * s;
  const sqrtD = Math.sqrt(discriminant);
  if (Number.isInteger(sqrtD)) {
    const k = (1 + sqrtD) / 2;
    if (k % 2 === 1) {
      solutions.push(k * multiple);
    }
  }
  // 递归边界:剩余场次不足时停止
  if (s - multiple < 0) return solutions;
  // 进入下一层2的倍数计算
  return reverseQweRecursive(s - multiple, multiple * 2, solutions);
}

// 测试用例
console.log(reverseQweRecursive(3)) // 输出 [3,4]
console.log(reverseQweRecursive(6)) // 输出 [6]
console.log(reverseQweRecursive(10)) // 输出 [5]

补充说明

部分总场次会对应多个合法初始人数,比如总场次为3时,3人(奇数直接单循环打3场)和4人(两两对战2场剩2人,再打1场剩1人结束,总场次3)都是合法解,上述两个实现都会返回所有符合的结果,如果只需要最小/最大解,返回对应位置的元素即可。

内容的提问来源于stack exchange,提问作者Rurohi53

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 17:21:01