2/17 (Fri): 이코테 기출문제 (구현)

Minsang Kang·2023년 2월 17일
0

TIL

목록 보기
7/12

이코테 유형별 기출문제

구현

자물쇠와 열쇠

풀이 특징

  • 완전 탐색 (모든 경우 확인)
  • 열쇠 크기(m) <= 자물쇠 크기(n) -> 3*n 크기의 자물쇠로 확인 가능
  • 열쇠 행렬 90도 회전 함수 구현 필요: nm행렬 (i, j) -> mn행렬 (j, n-1-i)
  • 열쇠 겹쳐지는 위치: range(2*n) 로 해결 가능
  • 중앙 부분 모두 1인지 확인 함수 구현 필요
  • 자물쇠를 *3 크기의 행렬로 키운 후 열쇠를 4번 회전하면서 확인
  • 열쇠를 위치한 후 값을 더한 새로운 열쇠행렬을 토대로 중앙값이 모두 1인지 확인
# 열쇠로 좌물쇠를 열 수 있으면 true, 없으면 false 를 return
import copy

# n*m 행렬 90 회전 -> m*n 행렬 반환                
def rotation(matrix):
    n = len(matrix)
    m = len(matrix[0])
    rotated = [[0]*n for _ in range(m)]
    
    for i in range(n):
        for j in range(m):
            rotated[j][(n-1)-i] = matrix[i][j]
            
    return rotated

# lock 중앙부분 1인지 확인
def check(new_lock):
    lock_length = len(new_lock) // 3
    for i in range(lock_length, lock_length * 2):
        for j in range(lock_length, lock_length * 2):
            if new_lock[i][j] != 1:
                return False
    return True

def solution(key, lock):
    n = len(lock)
    m = len(key)
    # 자물쇠의 크기를 기존의 3배로 변환
    new_lock = [[0]*(3*n) for _ in range(3*n)]
    for i in range(n):
        for j in range(n):
            new_lock[i+n][j+n] = lock[i][j]
            
    # 4가지 방향에 대해서 확인
    for _ in range(4):
        key = rotation(key)
        for x in range(2*n):
            for y in range(2*n):
                check_lock = copy.deepcopy(new_lock)
                # 자물쇠에 열쇠를 끼워 넣기
                for i in range(m):
                    for j in range(m):
                        check_lock[x+i][y+j] += key[i][j]
                
                if check(check_lock) == True:
                    return True
        
    return False

테스트통과 코드

  • 매초마다 머리 이동, 꼬리 이동하면서 확인
  • 머리, 꼬리 각각의 위치, 방향인자 필요
  • 커멘드 첫번째와 비교 후 커멘드시 방향전환, 꼬리용 커멘드 추가

답안 코드

  • 맵 범위 안에 있고, 뱀의 몸통이 없는 위치인지 확인
  • 사과가 없다면 이동 후에 꼬리 제거
  • 사과가 있다면 이동 후 에 꼬리 그대로 두기
  • 벽이나 뱀의 몸통과 부딪혔는지 확인
  • 다음 위치로 머리를 이동
  • 회전할 시간인 경우 회전
# 게임이 몇 초에 끝나는지 출력
from collections import deque
move = [(0, 1), (1, 0), (0, -1), (-1, 0)]
headDirection = 0
tailDirection = 0

n = int(input())
k = int(input())

graph = [[0]*n for _ in range(n)]
apples = []
for _ in range(k):
    x, y = map(int, input().split())
    graph[x-1][y-1] = 2

l = int(input())
commands = deque()
for _ in range(l):
    x, c = input().split()
    commands.append((int(x), c))

time = 0
headX, headY = 0, 0
tailX, tailY = 0, 0
graph[headX][headY] = 1
tailCommands = deque()
term = 1

while True:
    time += 1
    nextX, nextY = headX + move[headDirection][0], headY + move[headDirection][1]
    # 맵을 벗어난 경우
    if nextX < 0 or nextX >= n or nextY < 0 or nextY >= n:
        break
    # 몸과 만난 경우
    if graph[nextX][nextY] == 1:
        break
    # 머리 이동 반영
    headX, headY = nextX, nextY
    # 사과가 없는 곳으로 이동한 경우 꼬리 이동
    if graph[headX][headY] != 2:
        graph[tailX][tailY] = 0
        tailX, tailY = tailX + move[tailDirection][0], tailY + move[tailDirection][1]
    else:
        term += 1
    graph[headX][headY] = 1
    # 회전여부 확인
    if len(commands) != 0 and time == commands[0][0]:
        if commands[0][1] == 'D':
            headDirection += 1
        else:
            headDirection -= 1
        headDirection %= 4
        tailCommands.append((time+term, commands[0][1]))
        commands.popleft()
    # 꼬리 회전여부 확인
    if len(tailCommands) != 0 and time == tailCommands[0][0]:
        if tailCommands[0][1] == 'D':
            tailDirection += 1
        else:
            tailDirection -= 1
        tailDirection %= 4
        tailCommands.popleft()

print(time)
profile
 iOS Developer

0개의 댓글