LeeCode - 除数博弈
题目:
爱丽丝和鲍勃一起玩游戏,他们轮流行动。爱丽丝先手开局。
最初,黑板上有一个数字 N 。在每个玩家的回合,玩家需要执行以下操作:
选出任一 x,满足 0 < x < N 且 N % x == 0 。 用 N - x 替换黑板上的数字 N 。 如果玩家无法执行这些操作,就会输掉游戏。
只有在爱丽丝在游戏中取得胜利时才返回 true,否则返回 false。假设两个玩家都以最佳状态参与游戏。
示例 1:
输入:2 输出:true 解释:爱丽丝选择 1,鲍勃无法进行操作。 示例 2:
输入:3 输出:false 解释:爱丽丝选择 1,鲍勃也选择 1,然后爱丽丝无法进行操作。
分析:
第一反应我是去模拟这个游戏过程,也就是递推计算,这里我使用了一个数组去保存符合0 < x < N || N % x == 0要求的数字,然后通过 x 随机去取得其中的一个数,这里考虑到进行的终点是N == 2 || 3,因为当初始N为偶数时,X只能取偶数,最终将会取到2,而奇数则取到有可能取到2或者3,因为可以一直取1,这样N值将会在奇偶数之间摇摆,直到3。
我这里一开始没看清楚题目假设两个玩家都以最佳状态参与游戏,既然是最佳状态,那代表着能赢肯定赢,在 初始N为偶数的时候,爱丽丝只要一直拿1,鲍勃就不得不拿奇数,而偶数 - 奇数 - 1 = 偶数,故当N = 2的时候,爱丽丝赢。反之当N为奇数的时候,爱丽丝只能先手拿奇数,鲍勃只要一直取1,鲍勃赢。
我的答案:
答案:
var divisorGame = function (N, name) { //这个 name 用来描述此时取值的人 name == 1 ? 爱丽丝 :鲍勃
if (N == 1) { // N == 1 就没法玩了
return false
}
let arr = [] // 保存符合要求的数字
for (let i = 0; i < N; i++) {
if (N % i == 0 && i != 0) {
arr.push(i)
console.log(arr)
}
}
// 这里当两个人瞎玩,从满足条件的数字内取得随机数
let x = arr[parseInt(Math.random() * arr.length)]
if (N == 2) { // 判断递归终点
if (name == 1) {
return console.log("true")
}else {
return console.log("false") // 打印是为了在控制台看的见
}
} else if (N == 3) {
if (name == 2) {
return console.log("true")
} else {
return console.log("false")
}
}
name == 1 ? 2 : 1
divisorGame(N - x, name) // 递归
};
divisorGame(30, 1) // 测试一下,1 代表爱丽丝起手
结果:提交失败
标准解法
具体的思路上面已经说清楚了,在条件为假设两个玩家都以最佳状态参与游戏的情况下:
/**
* @param {number} N
* @return {boolean}
*/
var divisorGame = function(N) {
return (N % 2 == 0)
};
结果:提交成功
耗时:80ms
内存:33.7MB
审题不仔细,做题两行泪。。。