#Chapter 04. 상하좌우

Wonder_Why (Today I learned)·2021년 12월 14일

🖼 상하좌우

여행가 A는 N x N 크기의 정사각형 공간 위에 서 있다. 이 공간은 1 x 1 크기의 정사각형으로 나누어져 있다. 가장 왼쪽 위 좌표는 (1, 1)이며, 가장 오른쪽 아래 좌표는 (N, N)에 해당한다. 여행가 A는 상, 하, 좌, 우 방향으로 이동할 수 있으며, 시작 좌표는 항상 (1, 1)이다. 우리 앞에는 여행가 A가 이동할 계획이 적힌 계획서가 놓여있다.
계획서에는 하나의 줄에 띄어쓰기를 기준으로 하여 L, R, U, D 중 하나의 문자가 반복적으로 적혀있다. 각 문자의 의미는 다음과 같다.

L : 왼쪽으로 한 칸 이동
R : 오른쪽으로 한 칸 이동
U : 위로 한 칸 이동
D : 아래로 한 칸 이동

이때 여행가 A가 N x N 크기의 정사각형 공간을 벗어나는 움직임은 무시된다.
계획서가 주어졌을 때 여행가 A가 최종적으로 도착할 지점의 좌표를 출력하는 프로그램을 작성하시오

입력 조건
첫째 줄에 공간의 크기를 나타내는 N이 주어진다. (1 <= N <= 100)
둘째 줄에 여행가 A가 이동할 계획서 내용이 주어진다.
(1 <= 이동 횟수 <= 100)

출력 조건
첫째 줄에 여행가 A가 최종적으로 도착할 지점의 좌표(X, Y)를 공백으로 구분하여 출력한다.

입력 예시

5
R R R U D D

출력 예시

3 4

🎄변수 선언 부분

  int dx[4]={0,0,-1,1};
  int dy[4]={-1,1,0,0};
  char moveTypes[4]={'L','R','U','D'};
  int size;
  int x =1 , y= 1;
  string input;

(1) x, y는 좌표값이 아닌 행/열 인덱스를 표현하기로 하였다.
(2) map 을 구현하지 않고, 행/열 인덱스의 초기 값이 (1,1) 이므로, 주어진 입력에 대한 변화만 체크하기로 하였다.
(3) 움직일 수 있는 명령어를 char 형 배열 moveTypes 에 저장하였고, 각각 명령어에 따른 x 변화량, y 변화량을 dx[4], dy[4] 배열에 저장해두었다.
(4) int size; 는 map 의 크기를 나타내는 것으로 사용자로부터 입력을 받는다.
(5) int x = 1 , y= 1 는 초기 위치
(6) input 은 공백을 무시하고 '\n' 까지 받아야 하므로 string 객체로 선언하였고, getline(cin, input)으로 받을 예정

🎨 사용자 입력 부분

  cin >> size;
  cin.ignore();  // 버퍼 비우고
  getline(cin,input); // \n 포함해서 입력 받고

cin 으로 map 의 크기(size)를 입력받는다. 이때 '\n' 는 size 에 포함되지 않고, buffer 에 남아있고, 차후에 buffer 를 읽어들이는 경우에 의도치 않은 입력을 받게 될 수 있다.( getline 으로 받으면 아마 바로 끝나게 될 것. )
그렇기 때문에 cin.ignore(); 을 이용하여 cin_buffer 에 남아있는 값을 제거한 뒤, getline(cin,input)을 통해 명령어를 받는다.

  • c/c++ 의 표준입출력함수는 추후에 한 번에 정리할 예정!

✨ 핵심

for(int i = 0 ; i < input.size();i++)
  {
    char plan = input[i];
    int nx = 0 , ny = 0;
    for(int j = 0 ; j <4; j++)
    {
      if(moveTypes[j] == plan)
      {
        nx = x + dx[j];
        ny = y + dy[j];
      }
    }

  if(nx<1||ny<1||nx>size||ny>size) // map 을 벗어나서 움직이려고 하는 경우
  {
    continue;
  }
  else
    {
      x = nx;
      y = ny;
    }

  }

(1) 입력받은 명령어(RRRUDD...) 를 차례대로 읽어들인다.
(2) nx = ny = 0 을 선언하였고, 각 명령어에 따라 변하게 되는 행/열 인덱스 값을 nx,ny에 저장한 다음 map 을 벗어나지 않는다면(문제의 조건) x와 y에 해당 값을 업데이트한다.
(3) 명령어는 4개이므로, 내부 루프에서는 j<4
(4) moveTypes[j] == plan 인 경우에 해당하는 행/열 변화량 + 초기값을 각각 nx,ny에 저장
(5) 입력받은 명령어로부터 변화한 x,y 는 nx, ny인데, 문제의 조건(맵 밖으로 떨어지면 안됨)을 만족하면 x,y 에 그대로 업데이트 해주고 그렇지 않으면 그냥 반복문을 진행시켜 해당 명령어를 무시해준다.


코드 전문

#include <iostream>
#include <string>

using namespace std;

int main()
{ 
  int dx[4]={0,0,-1,1};
  int dy[4]={-1,1,0,0};
  char moveTypes[4]={'L','R','U','D'};
  int size;
  int x =1 , y= 1;
  string input;

  cin >> size;
  cin.ignore();  // 버퍼 비우고
  getline(cin,input); // \n 포함해서 입력 받고

  for(int i = 0 ; i < input.size();i++)
  {
    char plan = input[i];
    int nx = 0 , ny = 0;
    for(int j = 0 ; j <4; j++)
    {
      if(moveTypes[j] == plan)
      {
        nx = x + dx[j];
        ny = y + dy[j];
      }
    }

  if(nx<1||ny<1||nx>size||ny>size) // map 을 벗어나서 움직이려고 하는 경우
  {
    continue;
  }
  else
    {
      x = nx;
      y = ny;
    }

  }

  cout << x << " " << y;

  return 0;
}
profile
전자과 머학생

0개의 댓글