L 型组件填图问题
1.问题描述
设 B 是一个 n×n 棋盘,n=2 k,(k=1,2,3,…)。用分治法设计一个算法,使得:用若干个 L 型条块可以覆盖住 B 的除一个特殊方格外的所有方格。其中,一个 L 型条块可以覆盖 3 个 方格。且任意两个 L 型条块不能重叠覆盖棋盘。
例如:如果 n=2,则存在 4 个方格,其中,除一个方格外,其余 3 个方格可被一 L 型条 块覆盖;当 n=4 时,则存在 16 个方格,其中,除一个方格外,其余 15 个方格被 5 个 L 型条 块覆盖。
2. 具体要求
输入一个正整数 n,表示棋盘的大小是 n*n 的。输出一个被 L 型条块覆盖的 n*n 棋盘。 该棋盘除一个方格外,其余各方格都被 L 型条块覆盖住。为区别出各个方格是被哪个 L 型条 块所覆盖,每个 L 型条块用不同的数字或颜色、标记表示。
3. 测试数据
输入:8
输出:
import random;
count = 0
def initMap(n):
res = []
for i in range(n):
arr = [0] * n # 大坑
res.append(arr)
return res
def fill(src, half, x, y, direction):
global count
count += 1
if direction == 0:
src[half + x][half + y] = count
src[half + x - 1][half + y] = count
src[half + x][half + y - 1] = count
elif direction == 1:
src[half + x][half + y] = count
src[half + x - 1][half + y - 1] = count
src[half + x - 1][half + y] = count
elif direction == 2:
src[half + x][half + y] = count
src[half + x - 1][half + y - 1] = count
src[half + x][half + y - 1] = count
elif direction == 3:
src[half + x - 1][half + y - 1] = count
src[half + x - 1][half + y] = count
src[half + x][half + y - 1] = count
def splitMap(src, n, par_x, par_y, x, y):
if n == 1:
return
half = n // 2;
if (x + half) > par_x and (y + half) > par_y: # 特殊点在左上棋盘
fill(src, half, x, y, 0)
splitMap(src, half, par_x, par_y, x, y)
# 除去特殊点所在棋盘的递归外进行剩余棋盘递归
splitMap(src, half, x + half, y + half - 1, x + half, y) # 右上
splitMap(src, half, x + half - 1, y + half, x, y + half) # 左下
splitMap(src, half, x + half, y + half, x + half, y + half) # 右下
elif (x + half) <= par_x and (y + half) > par_y: # 特殊点在右上棋盘
fill(src, half, x, y, 1)
splitMap(src, half, par_x, par_y, x + half, y)
splitMap(src, half, x + half - 1, y + half - 1, x, y) #左上
splitMap(src, half, x + half - 1, y + half, x, y + half) # 左下
splitMap(src, half, x + half, y + half, x + half, y + half) # 右下
elif (x + half) > par_x and (y + half) <= par_y: # 特殊点在左下棋盘
fill(src, half, x, y, 2)
splitMap(src, half, par_x, par_y, x, y + half)
splitMap(src, half, x + half - 1, y + half - 1, x, y) #左上
splitMap(src, half, x + half, y + half - 1, x + half, y) # 右上
splitMap(src, half, x + half, y + half, x + half, y + half) # 右下
elif (x + half) <= par_x and (y + half) <= par_y: # 特殊点在右下棋盘
fill(src, half, x, y, 3)
splitMap(src, half, par_x, par_y, x + half, y + half)
splitMap(src, half, x + half - 1, y + half - 1, x, y) #左上
splitMap(src, half, x + half, y + half - 1, x + half, y) # 右上
splitMap(src, half, x + half - 1, y + half, x, y + half) # 左下
def fillMap(n, par_x, par_y):
src = initMap(n)
splitMap(src, n, par_x=par_x, par_y=par_y, x=0, y=0)
return src
def showMap(res, n):
print()
for i in range(n):
for j in range(n):
print(res[i][j], end='\t')
print()
n = int(input())
x = random.randint(0, n)
y = random.randint(0, n)
res = fillMap(n, par_x=x, par_y=y)
showMap(res, n)
# 1 1 1 1
# 1 0 0 1
# 1 0 0 1
# 1 1 1 1
# 1 1 2 2 0 0 0 0
# 1 4 4 2 0 0 0 0
# 3 4 5 5 0 0 0 0
# 3 3 5 0 0 0 0 0
# 0 0 0 0 0 0 0 0
# 0 0 0 0 0 0 0 0
# 0 0 0 0 0 0 0 0
# 0 0 0 0 0 0 0 0
?
|