益智游戏磁铁涉及将一组多米诺骨形磁铁(或驻极体或其他极化物体)放置在板上的插槽子集中,以满足一组约束。例如,左边的难题的解决方案在右边显示:
每个插槽都包含一个空白条目(用“ x”表示)或一个带有正极和负极端的“磁铁”。左侧和顶部的数字表示特定行或列中“ +”号的数量。右边和底部的那些在特定的行或列中显示“-”号的数量。一端或两端没有数字的行和列不受“ +”或“-”符号的数量的限制,具体取决于不存在哪个数字。除了满足这些数字约束之外,难题解决方案还必须满足以下约束:两个正交的正方形不能具有相同的符号(对角连接的正方形不受约束)。
给您的top [],bottom [],left [],right []数组分别表示沿着top(+),bottom(-),left(+)和right(-)边的+或–计数。值-1表示任意数量的+和–符号。还给出矩阵规则[] []包含任何一个T,B,L或R字符。对于板上的垂直插槽,T表示其顶端,B表示底端。对于板上的水平插槽,L表示左端,R表示右端。
例子:
Input : M = 5, N = 6
top[] = { 1, -1, -1, 2, 1, -1 }
bottom[] = { 2, -1, -1, 2, -1, 3 }
left[] = { 2, 3, -1, -1, -1 }
right[] = { -1, -1, -1, 1, -1 }
rules[][] = { { L, R, L, R, T, T },
{ L, R, L, R, B, B },
{ T, T, T, T, L, R },
{ B, B, B, B, T, T },
{ L, R, L, R, B, B }};
Output : + - + - X -
- + - + X +
X X + - + -
X X - + X +
- + X X X -
Input : M = 4, N = 3
top[] = { 2, -1, -1 }
bottom[] = { -1, -1, 2 }
left[] = { -1, -1, 2, -1 }
right[] = { 0, -1, -1, -1 }
rules[][] = { { T, T, T },
{ B, B, B },
{ T, L, R },
{ B, L, R } };
Output : + X +
– X –
+ – +
– + –
我们可以使用Backtracking解决此问题。
# Write Python3 code here
M = 5
N = 6
top = [ 1, -1, -1, 2, 1, -1 ]
bottom = [ 2, -1, -1, 2, -1, 3 ]
left = [ 2, 3, -1, -1, -1 ]
right = [ -1, -1, -1, 1, -1 ]
rules = [["L","R","L","R","T","T" ],
[ "L","R","L","R","B","B" ],
[ "T","T","T","T","L","R" ],
[ "B","B","B","B","T","T" ],
[ "L","R","L","R","B","B" ]];
def canPutPatternHorizontally(rules,i,j,pat):
if j-1>=0 and rules[i][j-1] == pat[0]:
return False
elif i-1>=0 and rules[i-1][j] == pat[0]:
return False
elif i-1>=0 and rules[i-1][j+1] == pat[1]:
return False
elif j+2 < len(rules[0]) and rules[i][j+2] == pat[1]:
return False
return True
def canPutPatternVertically(rules,i,j,pat):
if j-1>=0 and rules[i][j-1] == pat[0]:
return False
elif i-1>=0 and rules[i-1][j] == pat[0]:
return False
elif j+1 < len(rules[0]) and rules[i][j+1] == pat[0]:
return False
return True
def doTheStuff(rules,i,j):
if rules[i][j] == "L" or rules[i][j] == "R":
# option 1 +-
if canPutPatternHorizontally(rules,i,j,"+-"):
rules[i][j] = "+"
rules[i][j+1] = "-"
solveMagnets(rules,i,j)
# option 2 -+
# option 3 xx
def checkConstraints(rules):
pCountH = [0 for i in range(len(rules))]
nCountH = [0 for i in range(len(rules))]
for row in range(len(rules)):
for col in range(len(rules[0])):
ch = rules[row][col]
if ch == "+":
pCountH[row] += 1
elif ch == "-":
nCountH[row] += 1
pCountV = [0 for i in range(len(rules[0]))]
nCountV = [0 for i in range(len(rules[0]))]
for col in range(len(rules[0])):
for row in range(len(rules)):
ch = rules[row][col]
if ch == "+":
pCountV[col] += 1
elif ch == "-":
nCountV[col] += 1
for row in range(len(rules)):
if left[row] != -1:
if pCountH[row] != left[row]:
return False
if right[row] != -1:
if nCountH[row] != right[row]:
return False
for col in range(len(rules[0])):
if top[col] != -1:
if pCountV[col] != top[col]:
return False
if bottom[col] != -1:
if nCountV[col] != bottom[col]:
return False
#
# if (top[col] != -1 and pCountH[col] != top[col]) or (bottom[col] != -1 and nCountH[col] != bottom[col]) :
# return False
return True
def solveMagnets(rules,i,j):
if i == len(rules) and j == 0:
# check the constraint before printing
if checkConstraints(rules):
print(rules)
elif j >= len(rules[0]):
solveMagnets(rules,i+1,0)
# normal cases
else:
if rules[i][j] == "L":
# option 1 +-
if canPutPatternHorizontally(rules,i,j,"+-"):
rules[i][j] = "+"
rules[i][j+1] = "-"
solveMagnets(rules,i,j+2)
rules[i][j] = "L"
rules[i][j+1] = "R"
# option 2 -+
if canPutPatternHorizontally(rules,i,j,"-+"):
rules[i][j] = "-"
rules[i][j+1] = "+"
solveMagnets(rules,i,j+2)
rules[i][j] = "L"
rules[i][j+1] = "R"
# option 3 xx
if True or canPutPatternHorizontally(rules,i,j,"xx"):
rules[i][j] = "x"
rules[i][j+1] = "x"
solveMagnets(rules,i,j+2)
rules[i][j] = "L"
rules[i][j+1] = "R"
# vertical check
elif rules[i][j] == "T":
# option 1 +-
if canPutPatternVertically(rules,i,j,"+-"):
rules[i][j] = "+"
rules[i+1][j] = "-"
solveMagnets(rules,i,j+1)
rules[i][j] = "T"
rules[i+1][j] = "B"
# option 2 -+
if canPutPatternVertically(rules,i,j,"-+"):
rules[i][j] = "-"
rules[i+1][j] = "+"
solveMagnets(rules,i,j+1)
rules[i][j] = "T"
rules[i+1][j] = "B"
# option 3 xx
if True or canPutPatternVertically(rules,i,j,"xx"):
rules[i][j] = "x"
rules[i+1][j] = "x"
solveMagnets(rules,i,j+1)
rules[i][j] = "T"
rules[i+1][j] = "B"
else:
solveMagnets(rules,i,j+1)
# Driver code
solveMagnets(rules,0,0)
来源: https : //people.eecs.berkeley.edu/~hilfingr/programming-contest/f2012-contest.pdf