【Leetcode】292. Nim游戲


題目鏈接:https://leetcode-cn.com/problems/nim-game/description/

您和您的朋友,兩個人一起玩 Nim游戲:桌子上有一堆石頭,每次你們輪流拿掉 1 到 3 塊石頭。 拿掉最后一塊石頭的人就是勝利者。由您來開局。

你們兩個都是聰明人,相信都有最佳的游戲策略。 請編寫一個函數,來判斷您是否可以在給定的石頭數量的情況下贏得游戲。

比方說,如果堆中有4塊石頭,那么你永遠不會贏得比賽:無論你拿走的是 1塊,2塊 還是 3塊 石頭,最后一塊石頭總是會被你的朋友拿走。

 

這里做一個抽象,假設一推里面有n個石頭,每次可以取 1-m 個石頭。

顯然,如果n=m+1,那么由於一次最多只能取m個,所以,無論先取者拿走多少個,后取者都能夠一次拿走剩余的物品,后者取勝。這里我們就有一個想法了,假設這個石頭推為 (m+1)的倍數,那么第一個人取k( 1 <= k <= m)個,只要第二個人取 (m+1-k)個石頭,那么必定狀態能回到最初的狀態,m+1個。因為每個人都是很聰明的,取的石頭的個數一定要對自己有利。那么,假設最初石頭推不為 (m+1)的倍數。n=(m+1)r+s,那么第一個人只要取s個石頭必定能獲得勝利,反之,如果s == 0 ,那么第一個人必輸。

 

即,若n=k*(m+1),則后取着勝,反之,存在先取者獲勝的取法。n%(m+1)==0. 先取者必敗。

 

AC代碼:

1 public boolean canWinNim(int n) {
2 
3     return (n % 4) == 0 ? false : true;
4 }

 

(擴展):尼姆博弈

題型

尼姆博弈模型,大致上是這樣的:

有3堆各若干個物品,兩個人輪流從某一堆取任意多的物品,規定每次至少取1個,多者不限,最后取光者得勝。

獲勝情況對先取者的討論

異或結果為0,先取者必敗,無獲勝方法。后取者獲勝;

結果不為0,先取者有獲勝的取法。

 

拓展

任給N堆石子,兩人輪流從任一堆中任取(每次只能取自一堆),取最后一顆石子的人獲勝,問先取的人如何獲勝?

根據上面所述,N個數異或即可。如果開始的時候T=0,那么先取者必敗,如果開始的時候T>0,那么只要每次取出石子使得T=0,即先取者有獲勝的方法。

最后一個奇異局勢是(0,0...,0)。另一個奇異局勢是(n,n,0...0),只要對手總是和我拿走一樣多的物品,最后會面對(0,0...,0)。

 

SG函數模板:

 1 import java.util.Arrays;
 2 
 3 class Main {
 4     // N 表示可以取的個數
 5     // MAXN表示每堆石頭的最大數
 6     public static final int N = 20;
 7     public static final int MAXN = 1000;
 8     public static int[] f = new int[N];
 9     public static int[] SG = new int[MAXN + 10];
10     public static int[] S = new int[MAXN + 10];
11     
12     public static void main(String[] args) {
13         
14         
15     }
16     
17     void getSg(int n) {
18         int i, j;
19         Arrays.fill(SG, 0);
20         for (i = 1; i <= n; i++) {
21             Arrays.fill(S, 0);
22             for (j = 0; f[j] <= i && j < N; j++)
23                 S[SG[i - f[j]]] = 1;
24             for (j = 0;; j++)
25                 if (S[j] == 0) {
26                     SG[i] = j;
27                     break;
28                 }
29         }
30     }
31 }

 

 

 1 /*
 2 按照卡中心校園招聘的要求,HR小招和小商需要從三個科室中(分別為A、B、C)抽派面試官去往不同城市。
 3 兩名HR按照以下規定輪流從任一科室選擇面試官:每次至少選擇一位,至多選擇該科室剩余面試官數。最先選不到面試官的HR需要自己出差。
 4 假設HR小招和小商都不想出差且每次選擇都采取最優策略,如果是小招先選,寫一個函數來判斷她是否需要出差。如果不需要出差,請給出第一步的最優策略。
 5 */
 6 // 測試用例 2,0,4 -> c,2   1,8,9 -> 1(需要出差)
 7 public class Main{
 8     public static void main(String[] args) {
 9         Scanner in = new Scanner(System.in);
10         String string = in.next().toString();
11         String stringArray[] = string.split(",");
12         int num[] = new int[stringArray.length];
13         for (int i = 0; i < stringArray.length; i++) {
14             num[i] = Integer.parseInt(stringArray[i]);
15         }
16         int a = num[0];
17         int b = num[1];
18         int c = num[2];
19         int bool = a ^ b ^ c;
20         if (bool == 0)
21             System.out.print(1);
22         else {
23             if ((a ^ b) < c) {
24                 System.out.print("C," + (c - (a ^ b)));
25             }
26             if ((a ^ c) < b) {
27                 System.out.print("B," + (b - (a ^ c)));
28             }
29             if ((b ^ c) < a) {
30                 System.out.print("A," + (a -(b ^ c)));
31             }
32         }
33     }
34 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM