一个保险柜密码是三位数,如123,这个密码锁产生了故障,对上其中两位就可以打开(如1X2,X23)。问最坏情况下,至少试多少次才能保证打开?
1、正常算法:最坏情况就是 1000去掉28个能够打开的密码
(999 - 0 + 1)- 3 * 10 - 2 = 972个
【任选其中两位有3种情况,随后另外一位任意,则乘10,3位完全相同会出现3次,所以减2,剩一次。
2、 计算机遍历:
找出所有正确的答案
const random = require('lodash').random
const password = random(0,999).toString().padStart(3,0)
let count = 0
for(i=0; i<1000; i++) {
let flag = 0
const StringI = i.toString().padStart(3,0)
for (let j = 0; j < 3; j++) {
if (StringI[j] === password[j]) {
flag++
}
if (flag >= 2) {
count++
j = 3
}
if (j === 3) flag = 0
}
}
console.log(count, password)
3、探索人类极限算法(哈哈哈)
假设每一次都是随机的,疯狂尝试。这里times因为机器比较弱我设置五百万次,最高能探索到568。 几千万次的情况最多只能探索到600不到=。= 出现972的人估计运气逆天了
const random = require('lodash').random
const password = random(0,999).toString().padStart(3,0)
const result = Object.create(null)
let times = 1
console.log(password)
const guessIt = (key = 1, result, password) => {
let guess = random(0,999).toString().padStart(3,0)
let count = 0
return () => {
for (let i = 0; i < 3; i++) {
if (guess[i] === password[i]) {
count++
}
if (count >= 2) {
if (result[key]) {
result[key]++
} else {
result[key] = 1
}
return false
}
if (i === 2) {
return true
}
}
}
}
while (times <= 5000000) {
let key = 1
let flag = true
while (flag) {
flag = guessIt(key, result, password)()
key++
if (!flag) {
key = 1
}
}
times++
}
console.log(JSON.stringify(result))