본문 바로가기
코딩테스트

[구현, 시뮬레이션] 백준 8911. 거북이

by 말하는 감자에요 2025. 6. 10.
728x90
반응형

오늘은 간단한 시뮬레이션 문제를 가져왔습니다.

거북이를 이동시키며 지나간 영역의 최소 직사각형 넓이를 구하는 문제예요.

Let’s GO


1. 문제: 백준 8911. 거북이

문제


상근이는 2차원 평면 위에서 움직일 수 있는 거북이 로봇을 하나 가지고 있다. 거북이 로봇에게 내릴 수 있는 명령은 다음과 같이 네가지가 있다.

  1. F: 한 눈금 앞으로
  2. B: 한 눈금 뒤로
  3. L: 왼쪽으로 90도 회전
  4. R: 오른쪽으로 90도 회전

거북이

 

L과 R명령을 내렸을 때, 로봇은 이동하지 않고, 방향만 바꾼다. 명령을 나열한 것을 거북이 로봇의 컨트롤 프로그램이라고 한다.

 

상근이는 자신의 컨트롤 프로그램으로 거북이가 이동한 영역을 계산해보려고 한다. 거북이는 항상 x축과 y축에 평행한 방향으로만 이동한다. 거북이가 지나간 영역을 모두 포함할 수 있는 가장 작은 직사각형의 넓이를 구하는 프로그램을 작성하시오. 단, 직사각형의 모든 변은 x축이나 y축에 평행이어야 한다.

 

아래 그림에서 거북이는 가장 처음에 (0, 0)에 있고, 북쪽을 쳐다보고 있다. 컨트롤 프로그램이 FLFRFLBRBLB인 경우에 거북이는 아래와 같이 움직인다. 회색으로 빗금친 부분이 거북이가 지나간 영역을 모두 포함할 수 있는 가장 작은 직사각형이다. 넓이는 4가 된다.

거북이가 지나간 영역이 직사각형을 만들지 않는 경우도 있다. 예를 들어, FFLLFF인 경우에 거북이는 y축의 위로만 지나다닌다. 이 경우에 거북이가 지나간 영역을 모두 포함하는 직사각형은 선분이고, 선분은 한 변이 0인 직사각형으로 생각할 수 있다. 따라서, 선분의 경우에 넓이는 0이 된다.

입력


첫째 줄에 테스트 케이스의 개수 T가 주어진다. 각 테스트 케이스는 한 줄로 이루어져 있고, 컨트롤 프로그램이 주어진다. 프로그램은 항상 문제의 설명에 나와있는 네가지 명령으로만 이루어져 있고, 길이는 500을 넘지 않는다.

출력


각 테스트 케이스에 대해서, 거북이가 이동한 영역을 모두 포함하는 가장 작은 직사각형의 넓이를 출력한다.

예제 입력1


3
FFLF
FFRRFF
FFFBBBRFFFBBB

예제 입력2


2
0
9

2. 문제 풀이

시뮬레이션의 핵심

  1. 거북이의 현재 좌표 (x, y)와 방향을 추적합니다.
  2. 명령어를 하나씩 해석하며 이동을 시뮬레이션합니다.
  3. 이동할 때마다 최댓값/최솟값 좌표를 갱신합니다.
  4. 마지막에 직사각형 넓이를 가로 * 세로로 계산합니다.

📐 방향 설정

우리는 북→서→남→동 순서로 방향을 정의하고, 이를 0~3으로 매핑하여 회전 연산을 쉽게 합니다.

# 북, 서, 남, 동
dx = [0, -1, 0, 1]
dy = [1, 0, -1, 0]

구현 코드

def simulate(command):
    # 북, 서, 남, 동
    dx = [0, -1, 0, 1]
    dy = [1, 0, -1, 0]
    direction = 0
    x, y = 0, 0
    max_x, max_y, min_x, min_y = 0, 0, 0, 0

    for cmd in command:
        if cmd == 'F':
            x += dx[direction]
            y += dy[direction]
        elif cmd == 'B':
            x -= dx[direction]
            y -= dy[direction]
        elif cmd == 'L':
            direction = (direction + 3) % 4
        else:
            direction = (direction + 1) % 4
        
        min_x, min_y = min(min_x, x), min(min_y, y)
        max_x, max_y = max(max_x, x), max(max_y, y)
    
    return abs(max_x - min_x) * abs(max_y - min_y)
        
def main():
    T = int(input().strip())

    for _ in range(T):
        command = list(input().strip())
        print(simulate(command))

if __name__ == '__main__':
    main()

시간 복잡도

  • 테스트 케이스 수: 최대 T = 100
  • 명령어 길이: 최대 500
  • → O(T * N) = 최대 50,000회 연산으로 매우 충분합니다.

마무리

시뮬레이션 문제는 결국 문제 설명을 충실히 구현하는 것이 핵심입니다.

이 문제도 좌표 이동만 정확히 구현하면 충분히 풀 수 있습니다.

직사각형 넓이를 계산하는 부분에서 최대/최소 좌표 추적이 핵심이며, 방향 회전은 modulo 연산으로 처리하면 간단하게 구현할 수 있습니다.

🧭 오늘도 한 걸음 나아갔습니다! 내일도 한 문제씩, 꾸준히 쌓아보겠습니다 💪

728x90
반응형