Bạn có thể đã nghe nói về bảng điều khiển cổ điển bao gồm câu đố. Làm thế nào để bạn bao gồm một bàn cờ có một góc vuông bị thiếu, sử dụng gạch hình chữ L?Trực giác đằng sau bàn cờ bao gồm thuật toán đệ quy là gì và làm thế nào để có được tốt hơn trong việc xây dựng một thuật toán như vậy?
Có một cách tiếp cận đệ quy cho điều này như được giải thích trong cuốn sách "Thuật toán Python Làm chủ thuật toán cơ bản trong ngôn ngữ Python".
Ý tưởng là chia bảng thành 4 hình vuông nhỏ hơn, sau đó đặt gạch hình chữ L vào giữa bảng lớn hơn, tạo hiệu quả 4 hình vuông nhỏ hơn với một ô bị thiếu và tiếp tục qua đệ quy.
Về mặt khái niệm, thật dễ hiểu, nhưng tôi thấy rất khó để suy nghĩ về triển khai. Dưới đây là một giải pháp thực hiện -
def cover(board, lab=1, top=0, left=0, side=None):
if side is None: side = len(board)
# Side length
s = side // 2
# Offsets for outer/inner squares of subboards
offsets = ((0, -1), (side-1, 0))
for dy_outer, dy_inner in offsets:
for dx_outer, dx_inner in offsets:
# If the outer corner is not set...
if not board[top+dy_outer][left+dx_outer]:
# ... label the inner corner:
board[top+s+dy_inner][left+s+dx_inner] = lab
# Next label:
lab += 1
if s > 1:
for dy in [0, s]:
for dx in [0, s]:
# Recursive calls, if s is at least 2:
lab = cover(board, lab, top+dy, left+dx, s)
# Return the next available label:
return lab
để chạy mã này, bạn sẽ có được sau
board = [[0]*8 for i in range(8)]
board[7][7] = -1
cover(board)
for row in board:
print((" %2i"*8)%tuple(row))
3 3 4 4 8 8 9 9
3 2 2 4 8 7 7 9
5 2 6 6 10 10 7 11
5 5 6 1 1 10 11 11
13 13 14 1 18 18 19 19
13 12 14 14 18 17 17 19
15 12 12 16 20 17 21 21
15 15 16 16 20 20 21 -1
Tôi đã mất một thời gian để hiểu được điều này thực hiện. Tôi không chắc liệu tôi có hoàn toàn hiểu nó hay không, đặc biệt là suy nghĩ đằng sau đường lối tắt. Ai đó có thể cố gắng giải thích việc thực hiện một cách ngắn gọn? Làm thế nào để phát triển trực giác để suy nghĩ về một giải pháp cho các vấn đề thuộc loại này? Tôi tìm thấy giải pháp rất thông minh, đặc biệt là thiết lập các đường dây bù đắp như họ đã làm. Nếu ai đó có thể giúp tôi hiểu điều này và có lẽ gợi ý về cách trở nên tốt hơn, tôi sẽ đánh giá cao điều đó.
Cảm ơn!
Lời khuyên của tôi để hiểu code đệ quy: khi bạn phân tích một hàm đệ quy, giả định rằng nó đáp ứng đặc điểm kỹ thuật của nó, ví dụ: đối số cần vượt qua, nó bằng cách nào đó thực hiện hiệu quả mong đợi, giống như một hộp lại. Sau đó, với giả thuyết đó về các cuộc gọi nội bộ, bạn hiểu rõ hơn cách hoạt động của hàm. –
@ YvesDaoust: cảm ơn vì những nhận xét có giá trị. @ unutbu: đúng, nhưng giả định là một bảng kích thước 2 ** n. Tôi vẫn thấy khó có thể đưa ra cách tiếp cận đệ quy này. – yeehaw