[코테] dx, dy 테크닉(1)

dx,dy 테크닉

  • dx, dy 테크닉을 이용해 격자에서의 이동을 간결하게 구현하는 방법을 배움

dx, dy 테크닉?

  • 특정 방향에 대해 이동하는 경우, dx, dy 테크닉을 많이 사용한다.

기본 코드

image
  dir_num = 2 # 주어진 방향이 서쪽인 경우
  x, y = 1, 5 # 현재 위치가 (1,5)인 경우

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

  nx, ny = x + dx[dir_num], y + dy[dir_num]


방향에 맞춰 이동

문제

(0, 0)에서 시작하여 총 N번 움직여보려고 합니다. N번에 걸쳐 움직이려는 방향과 움직일 거리가 주어졌을 때, 최종 위치를 출력하는 프로그램을 작성해보세요. 단, dx, dy 테크닉을 활용하여 문제를 해결해주세요.

입력 형식

첫 번째 줄에 정수 N이 주어집니다. 두 번째 줄부터는 N개의 줄에 걸쳐 각 줄마다 이동방향과 이동한 거리가 공백을 사이에 두고 주어집니다. 방향은 W, S, N, E중에 하나이며 각각 서, 남, 북, 동쪽으로 이동함을 의미합니다.

  • 1 ≤ N ≤ 100
  • 1 ≤ 한 번에 움직이는 거리 ≤ 10

출력 형식

첫 번째 줄에 최종 위치 x, y를 공백을 사이에 두고 출력합니다.

입출력 예제

입력:
  4
  N 3
  E 2
  S 1
  E 2
출력:
  4 2


✔️ 문제 풀이

  n = int(input())
  x, y = 0, 0

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


  for _ in range(n) :
      dir_c, d = list(input().split())
      d = int(d)

      if dir_c == 'E':
          dir_num = 0
      elif dir_c == 'S':
          dir_num = 1
      elif dir_c == 'W':
          dir_num = 2
      else:
          dir_num = 3
      
      x, y = x + dx[dir_num] * d, y + dy[dir_num] * d
  print (x, y)

dx, dy 테크닉을 사용하기 위해서 먼저 동서남북 입력을 E, S, W, N로 주었으니까 dir_num으로 변경했다. 그리고 d만큼 이동했을 경우의 다음 위치를 구해주도록 했다.

  • 입력 받을 값의 개수가 정해져있으니 list() 함수 대신 tuple() 함수를 사용하는 게 좋을 듯 싶음
    • dir_c, d = tuple(input().split())

방향 회전을 위한 dx, dy 정의 방법

  • dx, dy를 정의할 때 방향 번호를 시계 방향 순서대로 적었다고 가정
  • 시계 방향으로 90’ 회전
    • dir_num = (dir_num + 1) % 4
    • dir_num을 1씩 증가시키면 되지만, dir_num = 3인 경우 다시 0으로 되어야 하니까 %4를 해준다.
  • 반시계 방향으로 90’ 회전
    • dir_num = (dir_num -1 + 4) % 4
    • 반대로 dir_num을 1씩 감소시키면 되지만, dir_num = 0인 경우 다시 3으로 되어야 하니까 양수 값을 가지기 위해 +4를 해준다.

문제

좌표평면 위 (0, 0)에서 북쪽을 향한 상태에서 움직이는 것을 시작하려 합니다. N개의 명령에 따라 총 N번 움직이며, 명령 L이 주어지면 왼쪽으로 90도 방향 전환을, 명령 R이 주어지면 오른쪽으로 90도 방향전환을 하고, 명령 F가 주어지면 바라보고 있는 방향으로 한칸 이동하려고 합니다. 이동 이후 최종 위치를 출력하는 프로그램을 작성해보세요.

입력 형식

첫 번째 줄에 문자 ‘L’, ‘R’, 그리고 ‘F’로만 이루어진 문자열이 하나 주어집니다.

  • 1 ≤ 명령의 길이 ≤ 100,000

출력 형식

최종 위치 (x, y)를 공백을 사이에 두고 출력합니다.

입출력 예제

입력:
  LF
출력:
  -1 0


✔️ 문제 풀이

  dirs = input()
  x, y = 0, 0
  dir_num = 3 # 북

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

  for dir_c in dirs :

      # 반시계 방향으로 90도 회전시
      if dir_c == "L": 
          dir_num = (dir_num - 1 + 4) % 4 
      
      # 시계 방향으로 90도 회전시
      elif dir_c == "R":
          dir_num = (dir_num + 1) % 4

      elif dir_c == "F":
          x += dx[dir_num]
          y += dy[dir_num]
          
  print (x, y)

dx, dy 테크닉을 이용해 주어진 입력을 for문을 돌면서 L, R이면 방향전환을 하고, F이면 현재 방향으로 한 칸 이동하도록 하였다.
시계방향으로 90도 회전 시에는 0->1, 1->2, 2->3으로 방향이 전환되어야 하고, 3->0으로 전환되어야 하기 때문에 dir_num = (dir_num + 1) % 4를 사용하였다. 반대인 반시계방향은 1->0, 2->1, 3->2로 방향이 전환되어야 하고, 0->3으로 전환되어야 하기 때문에 dir_num = (dir_num -1 + 4) % 4를 사용하였다.

문제출처: 코드트리의 문제 및 풀이를 정리한 내용입니다.

https://www.codetree.ai/missions/5/problems/move-in-direction?&utm_source=clipboard&utm_medium=text


© 2021. All rights reserved.

yaejinkong의 블로그