挑战35分钟 - 揭开神秘毒品的谜团

1,657 阅读3分钟

首先,让我们评估一下现有的信息和资源:

  • 12个试剂,其中1瓶有毒
  • 4张试纸,可以检测1滴就可以显示结果
  • 试纸15分钟后可以检测出毒性,试纸变红
  • 试纸可检验混合试剂
  • 有35分钟的时间限制

注:试纸不能撕毁,且试纸不可重复使用。

Q:如何筛选出有毒的试剂?

按照我们看到题目的第一思路,就是二分法。

  • 12分成2份,每份6瓶用第一个试纸。
  • 15min后,判断出有毒的那6瓶在分成两份,每份3瓶用第二个试纸。
  • 15min后,判断有毒的那3瓶用最后两张试纸。
  • 等待15min后,可筛选出有毒的那一瓶。

15 + 15 + 15 = 45 > 35

超过了时间限制,所以不太合理。

A: 我们来使用混合试剂的方法来测试。

  1. 现将试剂按照如下规则编号(就是转化成二进制)。
试剂号123456789101112
编号000100100011010001010110011110001001101010111100

2.四张试纸分别编号 ABCD。 将按照试剂编号上的 1 的位置来进行测试。 构建出这样的数据

{
    "A": "1000",
    "B": "0100",
    "C": "0010",
    "D": "0001"
}
试纸号编号
A8、9、10、11、12
B4、5、6、7、12
C2、3、6、7、10、11
D1、3、5、7、9、11

3.来匹配结果

结果编号答案
A10008
B01004
C00102
D00011
AB110012
AC101010
AD10019
BC01106
BD01015
CD00113
ABC111014 -
ABD110113 -
ACD101111
BCD01117
ABCD111115 -

将二进制的编号转成10进制即获取到有毒的试剂。其中13、14、15超出了12所以舍弃,不可能出现

我们来模拟一下这题目。

  • 首先设置三个变量,当作试剂试纸随机的有毒试剂号
/**
 * 试剂
 */
const reagent = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
/**
 * 试纸 0为白色 1为红色
 */
const testPaper = [0, 0, 0, 0]
/**
 * 随机有毒试剂
 */
const toxicIndex = Math.floor(Math.random() * reagent.length) + 1
  • 然后按照我们上面的逻辑一步一步向下写。
function fn() {
  // 1.将试剂编号
  let reagentNumbers = reagent.map(setAlias)
  // 2.将试剂分组
  const reagentList = [[], [], [], []]
  reagentNumbers.forEach((item) => {
    for (let i = 0; i < reagentList.length; i++) {
      if (item[i] === "1") {
        reagentList[i].push(item)
      }
    }
  })
  // 3.将对应的组倒入试纸
  const result = test(reagentList)
  const resultIndex = parseInt(result.join(""), 2)
  console.info("试纸结果是:", result)
  console.info("有毒的试剂是:" + toxicIndex)
  console.info("推算的试剂是:" + resultIndex)
}
  • 其中,我把setAlias编号方法、test测试方法抽出来。
/**
 * 设置试剂编号
 */
function setAlias(n) {
  n = n.toString(2)
  while (n.length < 4) {
    n = "0" + n
  }
  return n
}

/**
 * 测试试纸
 * @returns 返回15min后的试纸颜色
 */
function test(list) {
  const l = list.map((arr) => {
    return arr.map((item) => parseInt(item, 2))
  })
  return testPaper.map((item, index) => {
    return Number(l[index].includes(toxicIndex))
  })
}
  • 最后打印的结果是:

image.png

image.png

完整代码

/**
 * 试剂
 */
const reagent = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
/**
 * 试纸 0为白色 1为红色
 */
const testPaper = [0, 0, 0, 0]
/**
 * 随机有毒试剂
 */
const toxicIndex = Math.floor(Math.random() * reagent.length) + 1


/**
 * 设置试剂编号
 */
function setAlias(n) {
  n = n.toString(2)
  while (n.length < 4) {
    n = "0" + n
  }
  return n
}

/**
 * 测试试纸
 * @returns 返回15min后的试纸颜色
 */
function test(list) {
  const l = list.map((arr) => {
    return arr.map((item) => parseInt(item, 2))
  })
  return testPaper.map((item, index) => {
    return Number(l[index].includes(toxicIndex))
  })
}

function fn() {
  // 1.将试剂编号
  let reagentNumbers = reagent.map(setAlias)
  // 2.将试剂分组
  const reagentList = [[], [], [], []]
  reagentNumbers.forEach((item) => {
    for (let i = 0; i < reagentList.length; i++) {
      if (item[i] === "1") {
        reagentList[i].push(item)
      }
    }
  })
  // 3.将对应的组倒入试纸
  const result = test(reagentList)
  const resultIndex = parseInt(result.join(""), 2)
  console.info("试纸结果是:", result)
  console.info("有毒的试剂是:" + toxicIndex)
  console.info("推算的试剂是:" + resultIndex)
}

fn()