1275 找出井字棋的獲勝者(暴力破解)

1. 問題描述:

A 和 B 在一個 3 x 3 的網格上玩井字棋。

井字棋遊戲的規則如下:

玩家輪流將棋子放在空方格 (" ") 上。
第一個玩家 A 總是用 "X" 作爲棋子,而第二個玩家 B 總是用 "O" 作爲棋子。
"X" 和 "O" 只能放在空方格中,而不能放在已經被佔用的方格上。
只要有 3 個相同的(非空)棋子排成一條直線(行、列、對角線)時,遊戲結束。
如果所有方塊都放滿棋子(不爲空),遊戲也會結束。
遊戲結束後,棋子無法再進行任何移動。
給你一個數組 moves,其中每個元素是大小爲 2 的另一個數組(元素分別對應網格的行和列),它按照 A 和 B 的行動順序(先 A 後 B)記錄了兩人各自的棋子位置。

如果遊戲存在獲勝者(A 或 B),就返回該遊戲的獲勝者;如果遊戲以平局結束,則返回 "Draw";如果仍會有行動(遊戲未結束),則返回 "Pending"。

你可以假設 moves 都 有效(遵循井字棋規則),網格最初是空的,A 將先行動。

示例 1:

輸入:moves = [[0,0],[2,0],[1,1],[2,1],[2,2]]
輸出:"A"
解釋:"A" 獲勝,他總是先走。
"X  "    "X  "    "X  "    "X  "    "X  "
"   " -> "   " -> " X " -> " X " -> " X "
"   "    "O  "    "O  "    "OO "    "OOX"
示例 2:

輸入:moves = [[0,0],[1,1],[0,1],[0,2],[1,0],[2,0]]
輸出:"B"
解釋:"B" 獲勝。
"X  "    "X  "    "XX "    "XXO"    "XXO"    "XXO"
"   " -> " O " -> " O " -> " O " -> "XO " -> "XO " 
"   "    "   "    "   "    "   "    "   "    "O  "
示例 3:

輸入:moves = [[0,0],[1,1],[2,0],[1,0],[1,2],[2,1],[0,1],[0,2],[2,2]]
輸出:"Draw"
輸出:由於沒有辦法再行動,遊戲以平局結束。
"XXO"
"OOX"
"XOX"
示例 4:

輸入:moves = [[0,0],[1,1]]
輸出:"Pending"
解釋:遊戲還沒有結束。
"X  "
" O "
"   "

提示:

1 <= moves.length <= 9
moves[i].length == 2
0 <= moves[i][j] <= 2
moves 裏沒有重複的元素。
moves 遵循井字棋的規則。
來源:力扣(LeetCode)
鏈接:https://leetcode-cn.com/problems/find-winner-on-a-tic-tac-toe-game

2. 思路分析:

① 一開始的時候沒有啥思路,所以看了一下領釦的官方題解,其中python語言使用的是暴力破解的方法,思路如下:首先需要將贏的局面放在一個列表中,列表嵌套一個列表表示贏得可能性,每一種贏得可能性使用元組來表示贏得局面對應的座標

② 我們可以聲明兩個set集合(使用構造函數來生成一個空的集合)來添加雙方下的棋子對應的座標,每下一個棋子檢查當前的下棋者是否存在贏面,我們可以在循環中可以使用enumerate函數可以得到對應的下標以及對應的元素值,我們可以遍歷一開始聲明贏面的列表,依次檢查set集合中是否存在這樣的贏面即可

3. 代碼如下:

class Solution:
    def tictactoe(self, moves: List[List[int]]) -> str:
        # 下面的列表表示的是贏得一個局面
        wins = [
            [(0, 0), (0, 1), (0, 2)],
            [(1, 0), (1, 1), (1, 2)],
            [(2, 0), (2, 1), (2, 2)],
            [(0, 0), (1, 0), (2, 0)],
            [(0, 1), (1, 1), (2, 1)],
            [(0, 2), (1, 2), (2, 2)],
            [(0, 0), (1, 1), (2, 2)],
            [(0, 2), (1, 1), (2, 0)]
        ]
        # 判斷當前的集合是否有贏面: 在wins中依次檢查是否存在贏面
        def check(S):
            for win in wins:
                f = True
                for i in win:
                    if i not in S:
                        f = False
                        break
                if f: return True
            return False

        # 使用構造函數創建空的set集合
        A, B = set(), set()
        # 使用enumerate進行迭代可以得到對應的下標以及下標對應的數據
        for i, (x, y) in enumerate(moves):
            # 模擬兩個人
            if i % 2 == 0:
                A.add((x, y))
                if check(A): return "A"
            else:
                B.add((x, y))
                if check(B): return "B"
        return "Draw" if len(moves) == 9 else "Pending"

 

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