본문 바로가기

알고리즘/프로그래머스

Summer/Winter Coding(~2018) 방문 길이

목차

    문제

    https://school.programmers.co.kr/learn/courses/30/lessons/49994

     

    프로그래머스

    코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.

    programmers.co.kr

     


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

    U: 위쪽으로 한 칸 가기

    D: 아래쪽으로 한 칸 가기

    R: 오른쪽으로 한 칸 가기

    L: 왼쪽으로 한 칸 가기

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

    방문길이1_qpp9l3.png

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

    방문길이2_lezmdo.png

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

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

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

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

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

    방문길이5_nitjwj.png

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

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

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

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

     

     

     

     

     

     

     

    풀이

    문제의 핵심은 '왔던 길을 체크해야 하는 것'

     

    이 과정에서 더욱 중요한 것은 양방향 길을 체크해야 한다는 것이다.

    즉, 'A -> B'로 이동할 때의 경로를 체크하는 것 뿐만 아니라 'B -> A'로 이동할 때 역시 매핑을 해주어야 한다.

    그렇기에, boolean[N][N] 2차원 배열이 아닌 방향을 탑재한 3차원 배열을 사용하였다.

    자세한 내용은 코드를 참고할 것.

    코드

     

    import java.util.*;
    class Solution {
        //LURD
        static final int[] DR = {0, -1, 0, 1};
        static final int[] DC = {-1, 0, 1, 0};
        static int[][] map = new int[11][11]; //우상단을 0,0으로 지정
        static boolean[][][] visit = new boolean[11][11][4]; //이전 방향까지 고민(3차원 배열) 
        static int r = 5; //5,5에서 시작
        static int c = 5; 
        static int answer = 0;
        public int solution(String dirs) {
            char[] command = dirs.toCharArray();
            for(char c : command) {
                switch(c) {
                    case 'L' : { solve(0); break;}
                    case 'U' : { solve(1); break;}
                    case 'R' : { solve(2); break;}
                    case 'D' : { solve(3); break;}
                }
            }
            return answer;
        }
        
        
        public void solve(int d) {
            int nr = r + DR[d];
            int nc = c + DC[d];
            if(cantGo(nr, nc)) return;
            if(!visit[nr][nc][d]) {
                answer++;
                visit[nr][nc][d] = true; //이쪽 방향 마킹
                visit[r][c][(d + 2) % 4] = true;  //반대로 nr nc에서 오는 방향도 마킹
            }
            r = nr; //이동
            c = nc;
        }
        
        public boolean cantGo(int r, int c) {
            if(r < 0 || c < 0 || r >= 11 || c >= 11) return true;
            return false;
        }
    }

    '알고리즘 > 프로그래머스' 카테고리의 다른 글

    요격 시스템 (LV.2)  (0) 2024.03.30
    [프로그래머스] 연속된 부분 수열의 합  (1) 2024.03.11
    광물 캐기 - Lv2  (1) 2023.12.06
    짝지어 제거하기 (Level 2)  (0) 2023.11.02
    기능개발(Level 2)  (0) 2023.11.02