coding test

[파이썬] 8911. 거북이

잔망루피 2021. 6. 21. 19:45

문제

상근이는 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

예제 출력 1 

2

0

9

 

 

💗 나의 풀이

 

import sys
input=sys.stdin.readline
T=int(input().rstrip())      # 테케 수
pos=[(0, 1), (-1, 0), (0, -1), (1, 0)]      # 북서남동

for t in range(T) :
    cur=[0, 0]   # 현재 위치
    rotate=0    # 회전
    min_xy=[0, 0]   # 가장 작은 x, y 좌표
    max_xy=[0, 0]   # 가장 큰 x, y 좌표
    cmd = input().rstrip()  # 명령어
    for c in cmd :
        if c == "F" :   # 전진
            cur[0]+=pos[rotate][0]
            cur[1]+=pos[rotate][1]
        elif c == "B" :     # 후진
            cur[0]-=pos[rotate][0]
            cur[1]-=pos[rotate][1]
        elif c == "L" :     # 왼쪽 회전
            if rotate == 3 :rotate=0
            else : rotate+=1
        elif c == "R":      # 오른쪽 회전
            if rotate == 0 : rotate=3
            else : rotate-=1
        
        # 갱신
        if min_xy[0] > cur[0] :
            min_xy[0]=cur[0]
        elif max_xy[0] < cur[0] :
            max_xy[0]=cur[0]
        if min_xy[1] > cur[1] :
            min_xy[1]=cur[1]
        elif max_xy[1] < cur[1] :
            max_xy[1]=cur[1]

    print((max_xy[0]-min_xy[0])*(max_xy[1]-min_xy[1]))

 

첨에 pos를 동서남북으로 했더니 엉망진창. 시계든 반시계 방향이든 순서대로 pos에 넣자

min_xy, max_xy를 매반복마다 갱신한다.

((가장 큰 x좌표)-(가장 작은 x좌표))*((가장 큰 y좌표)-(가장 작은 y좌표))가 넓이다.

L과 R 각각 인덱스가 처음 또는 끝에 있을 때 적당한 처리를 해준다.

L의 경우 동(3)에서 북(0)으로 돌아갈 수 있게 한다.

R은 북(0)에서 동(3)으로 돌아갈 수 있게 한다.

 

왼쪽 회전
오른쪽 회전

 

💛 다른사람 풀이

 

# https://hongcoding.tistory.com/8
n=int(input())

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

for i in range(n) :
    pos_x=0
    pos_y=0
    pos_dir=0   # 0북 1서 2남 3동
    move=list(input())
    trace=[(pos_x, pos_y)]
    for j in move :
        if j == 'F' :
            pos_x=pos_x+dx[pos_dir]
            pos_y=pos_y+dy[pos_dir]
        elif j == 'B' :
            pos_x=pos_x-dx[pos_dir]
            pos_y=pos_y-dy[pos_dir]
        elif j == 'L' :
            if pos_dir == 3 :
                pos_dir=0
            else :
                pos_dir+=1
        elif j == 'R' :
            if pos_dir == 0 :
                pos_dir=3
            else :
                pos_dir-=1

        trace.append((pos_x, pos_y))
    width=max(trace, key=lambda x:x[0])[0]-min(trace, key=lambda x : x[0])[0]
    height=max(trace, key=lambda x : x[1])[1]-min(trace, key=lambda x : x[1])[1]
    print(width*height)

 

북 -> 서 -> 남 -> 동

pos_dir이 1씩 증가하면 왼쪽 이동. pos_dir이 동쪽(3)일 때 1 증가하면 인덱스 에러이므로 if문으로 북쪽(0) 처리

1씩 감소하면 오른쪽 이동. pos_dir이 북쪽(0)일 때 -1 감소하면 if문으로 동쪽(3) 처리한다.

가로와 세로는 각각 큰 값에서 작은 값을 뺀다.

 

 

# https://lem0nad3.tistory.com/18
import sys
input=sys.stdin.readline

t=int(input())

def fr() :
    k[0]=min(now[0], k[0])
    k[1]=min(now[1], k[1])
    k[2]=max(now[0], k[2])
    k[3]=max(now[1], k[3])

def go(m) :
    for i in range(2) :
        now[i]+=p[m][i]
    fr()

while t :
    t-=1
    k=[0, 0, 0, 0]  # minX, minY, maxX, maxY
    s=list(input())
    now=[0, 0]
    d=0
    p=[[0, 1], [1, 0], [0, -1], [-1, 0]]
    for i in s :
        if i == "F" :
            go(d)
        if i == "B" :
            go((d+2)%4)
        if i == "L" :
            d-=1
            d%=4
        if i == "R" :
            d+=1
            d%=4
    print((k[2]-k[0])*(k[3]-k[1]))

 

fr() 함수는 x, y 각각 작은 값, 큰 값을 구해 갱신한다.

후진할 때 d+2를 하는 이유는 p의 좌표가 우, 상, 좌, 하여서 +2를 해야 우<->좌, 상<->하가 된다.

 

 

 

문제 출처 👉 백준

반응형

'coding test' 카테고리의 다른 글

[파이썬, Java] 주식가격  (0) 2021.06.29
[Python, Java] 프린터  (0) 2021.06.28
[파이썬, Java] 3568. iSharp  (0) 2021.06.21
[파이썬, Java] 2252. 줄 세우기  (0) 2021.06.16
[파이썬] 1197. 최소 스패닝 트리  (0) 2021.06.13