Programmers 방문길이

2 분 소요

문제설명

게임 캐릭터를 4가지 명령어를 통해 움직이려 합니다. 명령어는 다음과 같습니다.

  • U: 위쪽으로 한 칸 가기

  • D: 아래쪽으로 한 칸 가기

  • R: 오른쪽으로 한 칸 가기

  • L: 왼쪽으로 한 칸 가기

캐릭터는 좌표평면의 (0, 0) 위치에서 시작합니다. 좌표평면의 경계는 왼쪽 위(-5, 5), 왼쪽 아래(-5, -5), 오른쪽 위(5, 5), 오른쪽 아래(5, -5)로 이루어져 있습니다.

1 예를 들어, ULURRDLLU로 명령했다면

2

1번 명령어부터 7번 명령어까지 다음과 같이 움직입니다. 3

8번 명령어부터 9번 명령어까지 다음과 같이 움직입니다. 4

이때, 우리는 게임 캐릭터가 지나간 길 중 캐릭터가 처음 걸어본 길의 길이를 구하려고 합니다. 예를 들어 위의 예시에서 게임 캐릭터가 움직인 길이는 9이지만, 캐릭터가 처음 걸어본 길의 길이는 7이 됩니다. (8, 9번 명령어에서 움직인 길은 2, 3번 명령어에서 이미 거쳐 간 길입니다)

단, 좌표평면의 경계를 넘어가는 명령어는 무시합니다.

예를 들어, LULLLLLLU로 명령했다면

5

1번 명령어부터 6번 명령어대로 움직인 후, 7, 8번 명령어는 무시합니다. 다시 9번 명령어대로 움직입니다. 6

이때 캐릭터가 처음 걸어본 길의 길이는 7이 됩니다.

명령어가 매개변수 dirs로 주어질 때, 게임 캐릭터가 처음 걸어본 길의 길이를 구하여 return 하는 solution 함수를 완성해 주세요.

제한사항

  • dirs는 string형으로 주어지며, ‘U’, ‘D’, ‘R’, ‘L’ 이외에 문자는 주어지지 않습니다.
  • dirs의 길이는 500 이하의 자연수입니다.

입출력예

dirs answer
ULURRDLLU 7
LULLLLLLU 7

알고리즘

  • 캐릭터가 움직일 수 있는 UP(y+1), DOWN(y-1), RIGHT(x+1),LEFT(x-1) 방향에 맞게 dx, dy 배열을 선언해준다.
  • 맵은 -5부터 5까지이지만 배열의 인덱스는 0부터 시작하므로, +5씩 더해서 0~10까지 맵을 설정할 4차원 boolean 배열을 선언해준다 즉, 현재위치 (2차원), 이동위치(2차원)체크를 해야한다.
  • 캐릭터의 현재 위치를 저장할 변수(x,y)와 이동후 위치를 저장할 변수(nx,ny)을 선언한다
  • 맵을 우측으로 5칸씩 이동했으므로, 이동후의 변수 초기값을 5로 설정한다.
  • 주어진 문자열의 각 문자를 기준으로 탐색을 한다
  • 각 문자가 U,D,R,L에 따라 위에서 설정한 dx, dy의 인덱스에 맞게 0,1,2,3로 저장하고, 캐릭터의 위치를 이동시킨다
  • 만약 캐릭터의 이동 위치가 맵을 벗어났을 경우(맵의 범위는 0~10까지) 이전에 이동시킨 캐릭터를 원위치시킨다
  • 캐릭터가 처음 왔던 길인경우, 이전의 길 + 현재의 길 모두 체크표시를 한다

풀이

소스코드
class Solution {
    public static int[] dx = {0,0,1,-1};
    public static int[] dy = {1,-1,0,0};
    
    public static boolean [][][][] visit =new boolean[11][11][11][11];
    //맵의 크기 = -5~5까지이므로 11x11
    
    public int solution(String dirs) {
        int answer = 0;
        
        //캐릭터가 이동하기 전 위치-x,y
        int x = 0;
        int y = 0;
        //캐릭터가 이동한 후 위치 nextX, nextY
        int nextX = 5;
        int nextY = 5;
        //문제의 범위는 -5~5이고, 배열의 크기는 0~10이므로 시작 위치를 +5로 잡아준다
        int index = 0;
        
        for(int i=0;i<dirs.length();i++) {
            x = nextX;
            y = nextY;
            if(dirs.charAt(i) == 'U')
                index = 0;
            else if(dirs.charAt(i) == 'D')
                index = 1;
            else if(dirs.charAt(i) == 'R')
                index = 2;
            else if(dirs.charAt(i) == 'L')
                index = 3;
        
            // U, D, R L 에 맞는 캐릭터 위치 이동
            nextX += dx[index];
            nextY += dy[index];
            
            //이전에 움직인 범위에 의해 캐릭터의 위치가 지도를 벗어났을 경우
            if(nextX < 0 || nextY < 0 || nextX > 10 || nextY > 10){
                //다시 캐릭터를 전의 위치로 이동
                nextX -= dx[index];
                nextY -= dy[index];
                continue;
            }
            
            //캐릭터가 처음 걸어본 길일 경우
            if(!(visit[x][y][nextX][nextY]) && !(visit[nextX][nextY][x][y])) {
                //걸어본 길 체크 (집이 아닌 길이기 때문에 양방향으로 체크한다)
                visit[x][y][nextX][nextY] = true;
                visit[nextX][nextY][x][y] = true;
                answer ++;
            }
        }
        
        return answer;
    }
}

카테고리:

업데이트:

댓글남기기