Следва точно решение на задачата на Python:
clone = lambda m: [ x[:] for x in [y[:] for y in m] ] # deepcopy
def R( m, k, d=-1): #rotate right
o= clone(m)
o[k] = [ m[k][(a+d)%len(o[k])] for a in range(len(o[k]))]
return o
def L( m, k): return R(m,k,1) #rotate left
def U( m, k, d=1): #rotate up
o= clone(m)
for a in range(len(o)):
o[a][k]=m[(a+d)%len(o)][k]
return o
def D( m, k): return U(m,k,-1) #rotate down
def gen(m, m_goal, (F1, F2), D,queue):
""" generate all 1 move next states from current state m using F1,F2"""
for x in range(D):
for F in (F1, F2):
cmd=F.__name__ + str(x+1)
next = F(m, x)
if m == m_goal: # solved!!!
print >> open("SHIFTING.OUT","w"), " ".join(queue[0][1])
return True
queue.append( (next, queue[0][1] + [cmd] ) )
def solve(m, m_goal, M, N ):
"""solve by breadth first searching all posibilities."""
queue=[ (m, []) ];
while True:
if gen(m, m_goal, (U,D), M, queue):
return
if gen(m, m_goal, (L,R), N, queue):
return
del queue[0]
m = queue[0][0]
if __name__ == "__main__":
lines = open("SHIFTING.INP").readlines()
M,N,C = map(int, lines[0].split())
m=[]; m_goal=[]
for a in lines[1:N+1]:
m.append( map(int, a.split()) )
for a in lines[N+1:]:
m_goal.append( map(int, a.split()) )
solve( m, m_goal, M,N)
Пояснения:
Решението е малко дълго. Цели 50 реда. И сам не знам защо съм писал толкова много.
Това е напълно валидно решение и ако намеря начин да го направя на exe може и да участвам, затова никой да не мисли, че може да прати това на конкурса вместо мен.
Този алгоритъм намира най-краткото решение ГАРАНТИРАНО. Затова ако участвам никой няма шанс да ме бие по тази точка.
За ваше щастие този алгоритъм е малко бавен и затруднява компютъра дори и за простият пример от матрица 3 на 4.
Така че не се отчайвайте.
Поздрави,
Лук
|