首先,让我们评估一下现有的信息和资源:
- 12个试剂,其中1瓶有毒
- 4张试纸,可以检测1滴就可以显示结果
- 试纸15分钟后可以检测出毒性,试纸变红
- 试纸可检验混合试剂
- 有35分钟的时间限制
注:试纸不能撕毁,且试纸不可重复使用。
Q:如何筛选出有毒的试剂?
按照我们看到题目的第一思路,就是二分法。
- 12分成2份,每份6瓶用第一个试纸。
- 15min后,判断出有毒的那6瓶在分成两份,每份3瓶用第二个试纸。
- 15min后,判断有毒的那3瓶用最后两张试纸。
- 等待15min后,可筛选出有毒的那一瓶。
15 + 15 + 15 = 45 > 35
超过了时间限制,所以不太合理。
A: 我们来使用混合试剂的方法来测试。
- 现将试剂按照如下规则编号(就是转化成二进制)。
| 试剂号 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 编号 | 0001 | 0010 | 0011 | 0100 | 0101 | 0110 | 0111 | 1000 | 1001 | 1010 | 1011 | 1100 |
2.四张试纸分别编号 A、B、C、D。
将按照试剂编号上的 1 的位置来进行测试。
构建出这样的数据
{
"A": "1000",
"B": "0100",
"C": "0010",
"D": "0001"
}
| 试纸号 | 编号 |
|---|---|
| A | 8、9、10、11、12 |
| B | 4、5、6、7、12 |
| C | 2、3、6、7、10、11 |
| D | 1、3、5、7、9、11 |
3.来匹配结果
| 结果 | 编号 | 答案 |
|---|---|---|
| A | 1000 | 8 |
| B | 0100 | 4 |
| C | 0010 | 2 |
| D | 0001 | 1 |
| AB | 1100 | 12 |
| AC | 1010 | 10 |
| AD | 1001 | 9 |
| BC | 0110 | 6 |
| BD | 0101 | 5 |
| CD | 0011 | 3 |
| ABC | 1110 | 14 - |
| ABD | 1101 | 13 - |
| ACD | 1011 | 11 |
| BCD | 0111 | 7 |
| ABCD | 1111 | 15 - |
将二进制的编号转成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))
})
}
- 最后打印的结果是:
完整代码
/**
* 试剂
*/
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()