leetcode脑经急转弯问题分享

问题1025:除数博弈
爱丽丝和鲍勃一起玩游戏,他们轮流行动。爱丽丝先手开局。
最初,黑板上有一个数字 N 。在每个玩家的回合,玩家需要执行以下操作:
选出任一 x,满足 0 < x < N 且 N % x == 0 。
用 N - x 替换黑板上的数字 N 。
如果玩家无法执行这些操作,就会输掉游戏。
只有在爱丽丝在游戏中取得胜利时才返回 True,否则返回 false。假设两个玩家都以最佳状态参与游戏。

示例 1:

输入:2
输出:true
解释:爱丽丝选择 1,鲍勃无法进行操作。

示例 2:

输入:3
输出:false
解释:爱丽丝选择 1,鲍勃也选择 1,然后爱丽丝无法进行操作。

问题分析:由上述实例可以看出,爱丽丝拿到的是2,就会获得胜利,而拿到的是3,就不能取得胜利。
而2是偶数,3是奇数,由此我们可以大胆猜测一下,是不是拿到偶数的玩家比拿到奇数的玩家胜率高。
奇数的约数只能是奇数–比如9的约数是1 3 9;15的的约数是1 3 5 15;
偶数的约数可奇可偶–比如6的约数是1 2 3 6;等等。
无论N初始为多大的值,N的约数一定有1和它本身,那么所有的N都可以无脑找x=1来执行。当N=2时,玩家再叫1;另一名玩家得到的N=1,就无法进行操作,所以该游戏的终止数一定是N=2。由此可得谁可以抢到偶数这个点,无脑叫1,将对手逼到奇数,一直到N=2时就可以获得游戏胜利。
所以该题的关键点是奇偶数,判断N为奇数还是偶数即可;

class Solution {
    public boolean divisorGame(int N) {
    	//如果N是偶数返回ture,是奇数返回false
        return N%2==0;
    }
}

问题292:Nim游戏
你和你的朋友,两个人一起玩 Nim 游戏:桌子上有一堆石头,每次你们轮流拿掉 1 - 3 块石头。 拿掉最后一块石头的人就是获胜者。你作为先手。
你们是聪明人,每一步都是最优解。 编写一个函数,来判断你是否可以在给定石头数量的情况下赢得游戏。

示例:

输入: 4
输出: false
解释: 如果堆中有 4 块石头,那么你永远不会赢得比赛;
因为无论你拿走 1 块、2 块 还是 3 块石头,最后一块石头总是会被你的朋友拿走。

问题分析:由例题可得当数量还剩4快时,无论怎样都不会取得胜利。
该游戏的规则是最多取3块,最少取1块,所以第四块是怎么样都拿不到的,4这个点就有可能是取得游戏胜利的关键。玩这类游戏一定要把主动权掌握在自己手里,我们可以将”第四块石头“当作最后一块石头,也就是不能让对手拿到这”第四块石头"。首先考虑四的倍数,当我们先手时要保证石头数量不为四的倍数,否则主动权不在我们手中,反之可以轻易取胜。

class Solution {
    public boolean canWinNim(int n) {
    	//如果石头个数不是四的倍数返回true,是则返回false
        return n%4!=0;
    }
}

这两道题都是游戏类问题,刚做时可能会觉得无从下手,因为你没有搞清游戏规则,简单分析下来,发现取胜的关键是一个数或者一类数,这时问题就迎刃而解,代码也显得很简单明了。
总结:做题多动脑!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章