반응형

programmers.co.kr/learn/courses/30/lessons/60059

 

코딩테스트 연습 - 자물쇠와 열쇠

[[0, 0, 0], [1, 0, 0], [0, 1, 1]] [[1, 1, 1], [1, 1, 0], [1, 0, 1]] true

programmers.co.kr

import copy

def solution(key, lock):
    M, N, nN = len(key), len(lock), len(lock) + (2 * len(key)) - 2 
    if sum(sum(lock, [])) == N * N: return True # 자물쇠가 열려있음.
    # newLock은 key를 넣는것을 고려하여 lock 주변을 padding한 2차원 배열
    newLock = [[lock[y - M + 1][x - M + 1] if (M - 1) <= y <= (nN - M) and (M - 1) <= x <= (nN - M) else 0 for x in range(nN)] for y in range(nN)]
    
    keys = [key] # key를 회전 시키는것을 고려하여 4 종류로 저장.
    for i in range(3):
        temp = []
        for i in key[:]: 
            temp.append(i[::-1]) # row를 거꾸로 뒤집고 전체의 col과 row를 바꾸면 90도 회전임
        key = [[temp[j][i] for j in range(len(temp))] for i in range(len(temp[0]))]
        keys.append(key)

    opened = [[1 for x in range(N)] for y in range(N)] # lock이 열린 모양
    for y in range(nN - M + 1): # newLock의 범위에서 key를 넣을 수 있는 경우의 범위
        for x in range(nN - M + 1):
            for key in keys: # 한 위치에서 키 4번(회전) 넣어봄
                copy_lock = copy.deepcopy(newLock) # 원본 유지
                for i in range(M): # key를 넣었을 경우 newLock의 값을 알맞게 갱신
                    for j in range(M):
                        copy_lock[y + i][x + j] += key[i][j]

                if [[copy_lock[y][x] for x in range(M - 1, nN - M + 1)] for y in range(M - 1, nN - M + 1)] == opened:
                    return True # 키를 넣었을때 lock 부분이 모두 1이면 lock 해제

    return False # 모든 경우를 탐색해도 자물쇠가 열리지 않았음

→ 구현하는데 범위를 정해야 하는것들이 많아서 헷갈리긴 하지만,

문제 자체의 해결 방법을 찾는것은 어렵지 않았음.

 

copy_lock을 사용할때, newLock이 이중 리스트이고 요소의 추가 삭제가 아닌 요소의 값이 바뀌게 되므로

깊은 복사를 해줘야한다.

반응형

'IT study > 알고리즘 문제 풀이' 카테고리의 다른 글

외벽 점검  (0) 2021.02.26
기둥과 보 설치  (0) 2021.02.24
괄호 변환  (0) 2021.02.23
문자열 압축  (0) 2021.02.23
블록 게임  (0) 2021.02.23

+ Recent posts