题目:
爱丽丝和鲍勃一起玩游戏,他们轮流行动。爱丽丝先手开局。
最初,黑板上有一个数字 N 。在每个玩家的回合,玩家需要执行以下操作:
选出任一 x,满足 0 < x < N 且 N % x == 0 。
用 N - x 替换黑板上的数字 N 。
如果玩家无法执行这些操作,就会输掉游戏。
只有在爱丽丝在游戏中取得胜利时才返回 True,否则返回 False。假设两个玩家都以最佳状态参与游戏。
示例 1:
输入:2
输出:true
解释:爱丽丝选择 1,鲍勃无法进行操作。
示例 2:
输入:3
输出:false
解释:爱丽丝选择 1,鲍勃也选择 1,然后爱丽丝无法进行操作。
提示:
1 <= N <= 1000
方法一:
public boolean divisorGame(int n) {
if(n <= 0 || n > 1000){
return false;
}
Boolean alice = false;//默认爱丽丝-输
while (true){
Integer x = getNumber(n);//获取一个符合条件的数值
if(x == null){//如果再也拿不到数据则直接返回上一次结果
break;
}
n = n - x;//还可以继续玩耍
alice = !alice;//改变爱丽丝输赢的状态
}
return alice;
}
/**
* 从数字n中获取一个数,该数必须符合条件
* @param n
* @return
*/
private Integer getNumber(int n){
if(n <= 0 || n > 1000){
return null;
}
Integer x = null;
Boolean hasReturn = true;
for(int i = 1; i < n; i++){
if(i <= 0 || i > 1000){//不符合条件
hasReturn = false;
break;
}else if(n % i == 0){//找到符合条件的数,返回
x = i;
break;
}else {//继续执行
continue;
}
}
/**
* 如果有返回值,并且x不为空,则返回x。
* 这里有个情况是循环中一个符合条件的x都没有找到
*/
if(hasReturn && x != null){
return x;
}else {
return null;
}
}
方法二:
/**
* 数字N如果是奇数,它的约数必然都是奇数;若为偶数,则其约数可奇可偶。
* 无论N初始为多大的值,游戏最终只会进行到N=2时结束,那么谁轮到N=2时谁就会赢。
* 因为爱丽丝先手,N初始若为偶数,爱丽丝则只需一直选1,使鲍勃一直面临N为奇数的情况,这样爱丽丝稳赢;
* N初始若为奇数,那么爱丽丝第一次选完之后N必为偶数,那么鲍勃只需一直选1就会稳赢。
* 综述,判断N是奇数还是偶数,即可得出最终结果!
* @param n
* @return
*/
public boolean divisorGameTwo(int n) {
if(n <= 0 || n > 1000){
return false;
}
return (n % 2 == 0);
}