在一個2^k * 2^k個方格組成的棋盤中,若有一個方格與其他方格不同,則稱該方格為一特殊方格,且稱該棋盤為一個特殊棋盤。
顯然特殊方格在棋盤上出現的位置有4^k種情形.因而對任何k≥0,有4^k種不同的特殊棋盤。
下圖所示的特殊棋盤為 k=2 時 16 個特殊棋盤中的一個。
在棋盤覆蓋問題中,要用下圖中 4 中不同形態的 L 型骨牌覆蓋一個給定的特殊棋牌上除特殊方格以外的所有方格,且任何 2 個 L 型骨牌不得重疊覆蓋。
易知,在任何一個 2^k * 2^k 的棋盤中,用到的 L 型骨牌個數恰為 (4^k-1)/3 。
求解棋盤問題,可利用分治的策略。當 k>0 時,將 2^k * 2^k 棋盤分割為 4 個 2^(k-1) * 2^(k-1) 子棋盤,如下圖所示。
特殊方格必位於 4 個子棋盤之一,其余 3 個子棋盤中無特殊方格。用一個 L 型骨牌覆蓋這 3 個較小的棋盤的匯合處,如圖所示,將這 3 個無特殊方格的子棋盤轉化為特殊棋盤,從而將原問題化為 4 個較小規模的棋盤覆蓋問題。遞歸的使用 這種分割,直至棋盤簡化為 1x1 棋盤。
python實現代碼如下:
1 # coding =gbk 2 3 4 # tr左上角行號,tc左上角列號。dr特殊方格行號,dc特殊方格列號 5 def chessboard(board, size, tr, tc, dr, dc): 6 if size <= 1: 7 return 8 global tile 9 tile += 1 10 current_tile = tile 11 size //= 2 12 if dr < tr + size and dc < tc + size: 13 chessboard(board, size, tr, tc, dr, dc) 14 else: 15 board[tr + size - 1][tc + size - 1] = current_tile 16 chessboard(board, size, tr, tc, tr + size - 1, tc + size - 1) 17 if dr >= tr + size and dc < tc + size: 18 chessboard(board, size, tr + size, tc, dr, dc) 19 else: 20 board[tr + size][tc + size - 1] = current_tile 21 chessboard(board, size, tr + size, tc, 22 tr + size, tc + size - 1) 23 if dr < tr + size and dc >= tc + size: 24 chessboard(board, size, tr, tc + size, dr, dc) 25 else: 26 board[tr + size - 1][tc + size] = current_tile 27 chessboard(board, size, tr, tc + size, 28 tr + size - 1, tc + size) 29 if dr >= tr + size and dc >= tc + size: 30 chessboard(board, size, tr + size, tc + size, dr, dc) 31 else: 32 board[tr + size][tc + size] = current_tile 33 chessboard(board, size, tr + size, tc + size, 34 tr + size, tc + size) 35 36 37 tile = 0 38 chessboard_size = 4 39 board = [[0 for x in range(chessboard_size)] for y in range(chessboard_size)] 40 chessboard(board, chessboard_size, 0, 0, 1, 0) 41 42 board = [[row[i] for row in board] for i in range(len(board[0]))] 43 for lst in board: 44 print(lst)