天天看點

<LeetCode>三道腦筋急轉彎程式設計題

  1. 石子遊戲

    亞曆克斯和李用幾堆石子在做遊戲。偶數堆石子排成一行,每堆都有正整數顆石子 piles[i] 。

    遊戲以誰手中的石子最多來決出勝負。石子的總數是奇數,是以沒有平局。

    亞曆克斯和李輪流進行,亞曆克斯先開始。 每回合,玩家從行的開始或結束處取走整堆石頭。 這種情況一直持續到沒有更多的石子堆為止,此時手中石子最多的玩家獲勝。

    假設亞曆克斯和李都發揮出最佳水準,當亞曆克斯赢得比賽時傳回 true ,當李赢得比賽時傳回 false 。

    示例:

    輸入:[5,3,4,5]

    輸出:true

    解釋:

    亞曆克斯先開始,隻能拿前 5 顆或後 5 顆石子 。

    假設他取了前 5 顆,這一行就變成了 [3,4,5] 。

    如果李拿走前 3 顆,那麼剩下的是 [4,5],亞曆克斯拿走後 5 顆赢得 10 分。

    如果李拿走後 5 顆,那麼剩下的是 [3,4],亞曆克斯拿走後 4 顆赢得 9 分。

    這表明,取前 5 顆石子對亞曆克斯來說是一個勝利的舉動,是以我們傳回 true 。

    解題思路

    本題看似很麻煩,但是仔細思考可以發現規律,即當數組數目為偶數時,我們總可以得到每層最大的數,比如上面事例,一直目前最外層最大數為5,次外層最大數為4,第一層 的5我們肯定會得到,為了得到次外層最大數,我們隻需拿走第一個5,對方拿走最後的5,這個時候我們可以順利得到次外層最大的數,依次類推,我們總能得到每層最大的數。而當數組數目為奇數時,當我們拿走第一層最大數後,對方會按照上述方法拿到每層的最大數。是以我們可以發現規律即:當數組長度為偶數時,傳回ture,當數組數組為奇數時,傳回false;

    代碼如下:

class Solution {
    public boolean stoneGame(int[] piles) {
       return piles.length%2==0;
    }
}
           
<LeetCode>三道腦筋急轉彎程式設計題

注意:本題存在一些漏洞,比如當數組第一層存在一個大于其他數總和的數時,隻要第一個人拿到該數,則不管數組長度為多少都是該玩家獲勝。或着當數組每個元素數字相等,勝利的條件就成了拿的次數。

292.Nim遊戲

你和你的朋友,兩個人一起玩 Nim 遊戲:桌子上有一堆石頭,每次你們輪流拿掉 1 - 3 塊石頭。 拿掉最後一塊石頭的人就是獲勝者。你作為先手。

你們是聰明人,每一步都是最優解。 編寫一個函數,來判斷你是否可以在給定石頭數量的情況下赢得遊戲。

示例:

輸入: 4

輸出: false

解釋: 如果堆中有 4 塊石頭,那麼你永遠不會赢得比賽;

因為無論你拿走 1 塊、2 塊 還是 3 塊石頭,最後一塊石頭總是會被你的朋友拿走。

解題思路:

這一題可以嘗試從1往後枚舉歸納的去尋找題解,1,2,3,4隻有4是輸掉;

然後5,6,7,8的時候通過最優解讓對方去得到4即可,可推知8的情況下是失敗的;進而可以推知4的倍數都是無法通過最優操作推到1,2,3,既4的倍數石子會輸掉。

代碼如下:

class Solution {
    public boolean canWinNim(int n) {
        return n%4!=0;
    }
}
           
<LeetCode>三道腦筋急轉彎程式設計題

1025.除數博弈

愛麗絲和鮑勃一起玩遊戲,他們輪流行動。愛麗絲先手開局。

最初,黑闆上有一個數字 N 。在每個玩家的回合,玩家需要執行以下操作:

選出任一 x,滿足 0 < x < N 且 N % x == 0 。

用 N - x 替換黑闆上的數字 N 。

如果玩家無法執行這些操作,就會輸掉遊戲。

隻有在愛麗絲在遊戲中取得勝利時才傳回 True,否則傳回 false。假設兩個玩家都以最佳狀态參與遊戲。

示例:

輸入:2

輸出:true

解釋:愛麗絲選擇 1,鮑勃無法進行操作。

輸入:3

輸出:false

解釋:愛麗絲選擇 1,鮑勃也選擇 1,然後愛麗絲無法進行操作。

解題思路:

數字N如果是奇數,它的約數必然都是奇數;若為偶數,則其約數可奇可偶。

無論N初始為多大的值,遊戲最終隻會進行到N=2時結束,那麼誰輪到N=2時誰就會赢。因為愛麗絲先手,N初始若為偶數,愛麗絲則隻需一直選1,使鮑勃一直面臨N為奇數的情況,這樣愛麗絲穩赢;N初始若為奇數,那麼愛麗絲第一次選完之後N必為偶數,那麼鮑勃隻需一直選1就會穩赢。綜述,判斷N是奇數還是偶數,即可得出最終結果!

代碼如下:

class Solution {
    public boolean divisorGame(int N) {
        return N%2==0;
    }
}
           
&lt;LeetCode&gt;三道腦筋急轉彎程式設計題