1. 程式人生 > >[LeetCode] Chalkboard XOR Game 黑板亦或遊戲

[LeetCode] Chalkboard XOR Game 黑板亦或遊戲

We are given non-negative integers nums[i] which are written on a chalkboard.  Alice and Bob take turns erasing exactly one number from the chalkboard, with Alice starting first.  If erasing a number causes the bitwise XOR of all the elements of the chalkboard to become 0, then that player loses.  (Also, we'll say the bitwise XOR of one element is that element itself, and the bitwise XOR of no elements is 0.)

Also, if any player starts their turn with the bitwise XOR of all the elements of the chalkboard equal to 0, then that player wins.

Return True if and only if Alice wins the game, assuming both players play optimally.

Example:
Input: nums = [1, 1, 2]
Output: false
Explanation: 
Alice has two choices: erase 1 or erase 2. 
If she erases 1, the nums array becomes [1, 2]. The bitwise XOR of all the elements of the chalkboard is 1 XOR 2 = 3. Now Bob can remove any element he wants, because Alice will be the one to erase the last element and she will lose. 
If Alice erases 2 first, now nums becomes [1, 1]. The bitwise XOR of all the elements of the chalkboard is 1 XOR 1 = 0. Alice will lose.

Notes:

  • 1 <= N <= 1000
  • 0 <= nums[i] <= 2^16.

這道題介紹了一種亦或遊戲,寫在黑板上,(黑板一臉懵逼,跟我有個毛關係)。愛麗絲和鮑勃兩個人輪流擦除一個數字,如果剩下的數字亦或值為0的話,那麼當前選手就輸了。反過來也可以這麼說,如果某一個選手開始遊戲時,當前數字的亦或值為0了,那麼直接就贏了。現在給了我們一個數組,問先手的愛麗絲能否獲勝。那麼其實這道題是一道有技巧的題,並不是讓我們按照遊戲規則那樣去遍歷所有的情況,有海量的運算。這題有點像之前那道Nim Game,重要的是技巧!技巧!技巧!重要的事情說三遍~但我等凡夫俗子如何看的出技巧啊,看不出技巧只能看Discuss了,博主也沒看出來。但實際上這道題的解法可以非常的簡單,兩三行就搞定了。辣麼開始講解吧:首先根據題目的描述,我們知道了某個選手在開始移除數字之前,如果陣列的亦或值為0的話,選手直接獲勝,那麼先手愛麗絲在開始開始之前也應該檢查一遍陣列的亦或值,如果是0的話,直接獲勝。我們再來分析亦或值不為0的情況,既然不為0,那麼亦或值肯定是有一個值的,我們假設其是x。下面就是本題的精髓了,是要考慮陣列個數的奇偶情況(尼瑪誰能想到!),這個陣列個數一旦是偶數的話,就大有文章了,現在數字個數是偶數,且亦或值不為0,說明陣列中的數字不全相同,因為偶數個相同數字的亦或值為0,那麼愛麗絲只要移除一個不為x的數字就行了,這樣移除後陣列的亦或值也不會是0,那麼由於鮑勃也是個機智的boy,他也不會移除一個使得剩餘陣列亦或值為0的數字,but,到了最後一個數字時,鮑勃別無選擇只能移除最後一個數字,此時陣列為0,亦或值為0,愛麗絲獲勝。那此時你可能會有疑問,為啥奇數個數字且亦或值不為0時,愛麗絲一定會輸?因為即便愛麗絲先移除掉了一個數字,使得陣列亦或值仍不為0,那麼此時鮑勃面對的情況就是偶數個數字使得陣列亦或值不為0,這跟上面推論愛麗絲一定會贏的情況一樣,鮑勃也是個聰明的藍孩紙,所以愛麗絲會輸,參見程式碼如下:

解法一:

class Solution {
public:
    bool xorGame(vector<int>& nums) {
        int x = 0, n = nums.size();
        for (int num : nums) x ^= num;
        return x == 0 || n % 2 == 0;
    }
};

下面這種解法就很秀了,比大軍師大司馬吳秀波還秀,直接用個accumulate一行搞定亦或值,博主只想吐槽這道題的難度級別,大家有見過一行解出一道Hard題嗎,做夢都要笑醒了吧~

解法二:

class Solution {
public:
    bool xorGame(vector<int>& nums) {
        return nums.size() % 2 == 0 || !accumulate(nums.begin(), nums.end(), 0, bit_xor<int>());
    }
};

類似題目:

參考資料: