[코드트리 | 삼성] 메이즈 러너

2023. 10. 20. 17:46· 공부 기록/알고리즘 풀이
목차
  1. 문제 개요
  2. 풀이과정, 방향
  3. 유의점
  4. 코드
  5. 느낀점

문제 개요

  • 미로
    • M*M 격자 미로
    • 종류
      • 빈칸(참가자 이동 가능)
      • 벽(1-9의 내구도, 회전 시 내구도가 1씩 깎이고 0이 되면 빈칸이 됨)
      • 출구(참가자 도달 시 탈출)
    • 회전
      • 참가자 이동 후 회전
      • 한 명 이상의 참가자와 출구를 포함한 가장 작은 정사각형
        • 크기가 같다면 좌상단 r좌표가 작은 것, 그 후엔 c좌표가 작은 것이 우선
      • 선택된 정사각형은 시계방향으로 90도 회전, 회전된 벽은 내구도가 1씩 깎임
  • 참가자(M명)
    • 상하좌우, 벽이 없는 곳으로 이동
    • 움직인 칸은 현재 칸보다 출구에 가까워야 함
    • 움직일 수 없으면 움직이지 않음
    • 한 칸에 여러 참가자 있을 수 있음
    • 모든 참가자가 동시에 움직임
  • 종료조건
    • 모든 참가자가 탈출에 성공했을 때
    • K초가 지났을 때
  • 모든 참가자들의 이동 거리 합과 출구 좌표를 출력하기

문제를 위와 같이 정리할 수 있다.

풀이과정, 방향

수행해야 하는 과정은 참가자 이동 >> 회전할 정사각형 선정 >> 미로 회전 >> 게임 종료 조건 확인 순이므로 각각에 대한 함수를 만들어 해결한다.
이번 주 삼성 기출문제를 풀면서 느낀점은

  1. 동작을 나누어서 각각에 대한 함수를 만들어서 풀것
  2. 어줍잖게 sort같은거 사용해서 편하게 할 생각 말고 조건문으로 하나하나 예외처리 하면서 풀 것

이거 두가지인 것 같다. 그리고 두 명 이상의 참가자가 같은 칸에 있을 수 있고, 각각의 참가자의 위치를 알고 있는 것이 회전할 정사각형을 구하기에 편리하기 때문에 참가자들을 array로 관리하는 것이 편리할 것이다.

유의점

정사각형의 회전 좌표를 어떻게 둘지를 고민하는데 많은 시간이 걸릴 것이다. 전체 사각형이 회전하는 것이 아닌, 일부만을 회전시키는 것이기 때문에 좌표 변환이 헷갈렸는데, 처음부터 좌표를 분해하여 고민했다면 시간이 많이 단축되었을 것 같다.

코드

import copy
n, m, k = map(int, input().split())

maze = []
players = []

for i in range(n):
    arr  = list(map(int,input().split()))
    maze.append(arr)

for i in range(m):
    a,b = map(int, input().split())
    players.append([a-1, b-1])

ey, ex = map(int, input().split())
ey-=1
ex-=1



answer = 0
def player_move():
    global answer
    #플레이어는 벽이 없는 곳으로, 출구까지의 최단 거리가 가까운 곳으로 이동
    #움직일 수 있는 칸이 2개 이상이면, 상하로 움직이는 것이 우선
    left_players = len(players)
    for i in range(left_players):
        py, px = players.pop(0)

        # 출구가 플레이어보다 높은 y값이면 아래로 움직일 수 있나 확인
        if ey > py and maze[py+1][px] == 0:
            answer+=1
            if not(py+1==ey and px==ex):
                players.append([py+1, px])
        # 낮은 y값이면 위로 움직일 수 있나 확인
        elif ey < py and maze[py-1][px] == 0:
            answer+=1
            if not(py-1==ey and px==ex):
                players.append([py-1, px])
        # 높은 x값이면 오른쪽으로 움직일 수 있나 확인
        elif ex > px and maze[py][px+1] == 0:
            answer+=1
            if not(py==ey and px+1==ex):
                players.append([py, px+1])
        # 낮은 x값이면 왼쪽으로 움직일 수 있나 확인
        elif ex < px and maze[py][px-1] == 0:
            answer+=1
            if not(py==ey and px-1==ex):
                players.append([py, px-1])
        # 그 외에는 움직이지 않는다.
        else:
            players.append([py, px])


def find_rectangle():
    global ey, ex
    size = n
    left_y, left_x = 0,0
    for s in range(2, n+1):
        for i in range(n - s+1):
            for j in range(n - s+1):
                if i<= ey < i+s and j<= ex < j+s:
                    for py, px in players:
                        if i<= py < i+s and j<= px < j+s:
                            if s < size:
                                size = s
                                left_y, left_x = i,j
    return [size, left_y, left_x]


def turn_rectangle(size, left_y, left_x, maze):
    # 미로 회전
    new_maze = copy.deepcopy(maze)
    for i in range(size):
        for j in range(size):
            new_i = left_y+j
            new_j = left_x+size-1-i
            new_maze[new_i][new_j] = max(0, maze[left_y+i][left_x+j]-1)
    return new_maze

for i in range(k):
    # print(players)
    player_move()
    # print(players)
    if len(players)==0:
        break
    size, left_y, left_x = find_rectangle()
    maze = turn_rectangle(size, left_y, left_x, maze)
    # 출구 회전
    # print(ey, ex)
    ey, ex = left_y+ex-left_x, left_x+size+left_y-ey-1
    # print(ey, ex)
    # player 회전
    for i in range(len(players)):
        py, px = players[i]
        if left_y<=py<left_y+size and left_x<=px<left_x+size:
            # print(players[i])
            players[i] = [left_y+px-left_x, left_x+size+left_y-py-1]
            # print(players[i])

print(answer)
print(ey+1, ex+1)

느낀점

아까 위에서 정리한 두가지를 명심하면서 풀어야 할 것 같다.

  1. 동작을 나누어서 각각에 대한 함수를 만들어서 풀것
  2. 어줍잖게 sort같은거 사용해서 편하게 할 생각 말고 조건문으로 하나하나 예외처리 하면서 풀 것

'공부 기록 > 알고리즘 풀이' 카테고리의 다른 글

[240715] BOJ 16432 떡장수와 호랑이  (2) 2024.07.15
[240710] BOJ 2662 기업투자  (0) 2024.07.10
[Programmers | Lv.2] 스킬트리  (0) 2024.01.02
[코드트리 | 삼성] 코드트리 빵  (0) 2023.10.23
[코드트리 | 삼성] 포탑 부수기  (0) 2023.10.21
  1. 문제 개요
  2. 풀이과정, 방향
  3. 유의점
  4. 코드
  5. 느낀점
'공부 기록/알고리즘 풀이' 카테고리의 다른 글
  • [240710] BOJ 2662 기업투자
  • [Programmers | Lv.2] 스킬트리
  • [코드트리 | 삼성] 코드트리 빵
  • [코드트리 | 삼성] 포탑 부수기
IsItGettingBetter?
IsItGettingBetter?
I just think I'm two steps nearer to my grave
IsItGettingBetter?
Getting better
IsItGettingBetter?
전체
오늘
어제
  • 분류 전체보기 (25)
    • 공부 기록 (19)
      • 네트워크 (0)
      • 운영체제 (0)
      • 컴퓨터 시스템 (1)
      • 데이터베이스 (1)
      • 알고리즘 풀이 (6)
      • Java (3)
      • 강의 (1)
      • 자잘한것들 (6)
    • 취준 기록 (3)
      • SSAFY (1)
      • 공채 및 수시 지원 (2)
    • 여행 기록 (0)
    • - (2)

블로그 메뉴

  • 홈
  • 태그
  • 방명록

공지사항

인기 글

태그

  • 싸피11기
  • 개발도서
  • 취준
  • 코테준비
  • 자바객체지향의원리와이해
  • CSAPP
  • 취준기록
  • for-else문
  • 코드트리
  • SSAFY 11기
  • 알고리즘문제
  • 코테
  • while-else문
  • malloclab
  • SKT지원
  • 삼성SW역량테스트기출
  • 취준일상
  • 원티드 프리온보딩 챌린지
  • 알고리즘
  • 반복문else

최근 댓글

최근 글

hELLO · Designed By 정상우.v4.2.1
IsItGettingBetter?
[코드트리 | 삼성] 메이즈 러너
상단으로

티스토리툴바

단축키

내 블로그

내 블로그 - 관리자 홈 전환
Q
Q
새 글 쓰기
W
W

블로그 게시글

글 수정 (권한 있는 경우)
E
E
댓글 영역으로 이동
C
C

모든 영역

이 페이지의 URL 복사
S
S
맨 위로 이동
T
T
티스토리 홈 이동
H
H
단축키 안내
Shift + /
⇧ + /

* 단축키는 한글/영문 대소문자로 이용 가능하며, 티스토리 기본 도메인에서만 동작합니다.