棋盘覆盖问题

棋盘覆盖问题_第1张图片
百度百科

这个题要用到分治递归的技巧:
分治的技巧在于如何划分棋盘,使划分后的子棋盘的大小相同,并且每个子棋盘均包含一个特殊方格,从而将原问题分解为规模较小的棋盘覆盖问题。

Idea: 每次对方块进行田字格划分,然后都取方块中心的四个点,其中一个点所在的大方格里存在特殊方格,于是我们保持不动;剩下三个用L型方块占领。

要注意这里除了递归栈,其他的空间复杂度是O(1)。所以没有额外的申请空间,都是基于原table在操作。

时间复杂度:O(4^n)

# 棋盘覆盖

def form_2d_table(length, x, y):
    table= []
    for i in range(0, length):
        row = []
        for j in range(0, length):
            row.append('a')
        table.append(row)
    table[x][y] = 'b'

    return table


def divide(table, table_x, table_y, size, x, y):
    if size == 1:
        return

    global L_num
    mid = size//2
    x_mid = table_x + mid -1
    y_mid = table_y + mid -1


    if x > x_mid and y > y_mid:
        table[x_mid][y_mid] = L_num
        table[x_mid+1][y_mid] = L_num
        table[x_mid][y_mid+1] = L_num
        L_num += 1
        divide(table, table_x+mid, table_y + mid, mid, x, y)
        divide(table, table_x, table_y, mid, table_x + mid-1, table_y+mid-1)
        divide(table, table_x, table_y + mid, mid, table_x+mid-1, table_y+mid)
        divide(table, table_x + mid, table_y, mid, table_x+mid, table_y+mid-1)
      

    if x > x_mid and y <= y_mid:
        table[x_mid][y_mid] = L_num
        table[x_mid][y_mid + 1] = L_num
        table[x_mid + 1][y_mid + 1] = L_num
        L_num += 1

        divide(table, table_x, table_y, mid, table_x+mid-1, table_y+mid-1)
        divide(table, table_x, table_y+mid, mid, table_x+mid-1, table_y+mid)
        divide(table, table_x + mid, table_y, mid, x, y)
        divide(table, table_x+mid, table_y+mid, mid, table_x+mid, table_y+mid)

    if x <= x_mid and y > y_mid:
        table[x_mid][y_mid] = L_num
        table[x_mid + 1][y_mid] = L_num
        table[x_mid + 1][y_mid + 1] = L_num
        L_num += 1

        divide(table, table_x, table_y, mid, table_x + mid - 1, table_y + mid - 1)
        divide(table, table_x, table_y + mid, mid, x, y)
        divide(table, table_x + mid, table_y, mid, table_x + mid, table_y + mid - 1)
        divide(table, table_x + mid, table_y + mid, mid, table_x + mid, table_y + mid)

    if x <= x_mid and y <= y_mid:
        table[x_mid+1][y_mid+1] = L_num
        table[x_mid + 1][y_mid] = L_num
        table[x_mid][y_mid + 1] = L_num
        L_num += 1

        divide(table, table_x, table_y, mid, x, y)
        divide(table, table_x, table_y + mid, mid, table_x + mid-1, table_y + mid)
        divide(table, table_x + mid, table_y, mid, table_x + mid, table_y + mid-1)
        divide(table, table_x + mid, table_y + mid, mid, table_x + mid, table_y + mid)

size = 8
table = form_2d_table(size, 0, 0)

L_num = 0
divide(table, 0, 0, size, 0, 0)

for i in range(size):
    row = []
    for j in range(size):
        row.append(table[i][j])
    print(row)

你可能感兴趣的:(棋盘覆盖问题)