• [level2] 프로그래머스 - 빛의 경로 사이클(JAVA)

    2021. 9. 20.

    by. 데롱디롱

     

     

    문제가 잘 이해가지 않아서,
    질문하기에 문제 설명 보고나서 풀었다ㅠ

     

     

     

     

    [ 문제 풀이 ]

    - grid의 각 정점이 4방향 [상, 하, 좌, 우]로 들렸는지 여부를 저장할 3차 배열을 만들어준다.

     

    - 방향(d)의 순서는 '시계 방향' 혹은 '반시계 방향'처럼 쭉 이어지게 정해야 나중에 방향 전환을 계산할 때 편하다.
       나는 [ 아래, 왼, 위, 오른]의 순서로 정하고 dr, dc를 만들어주었다.

     

     

    - 각 정점마다 모든 들리지 않은 방향에 대하여 빛의 경로를 구해준다.   => light함수

     

     

    - 방문 처리를 하면서, 들리지 않은 방향으로 나아가본다.

    빛 S : 현재 방향을 유지
    빛 L : 좌회전
    빛 R : 우회전

    회전 방법은 여러 가지가 있다.
    본인의 d 순서에 맞게 잘 짜면 된다.
    if (grid[r].charAt(c) == 'L')
    	d = d == 0 ? 3 : d - 1; // 좌회전
    else if (grid[r].charAt(c) == 'R')
    	d = d == 3 ? 0 : d + 1; // 우회전​

    나는 위에처럼 짰지만, 이렇게도 될 것 같다.
    if (grid[r].charAt(c) == 'L')
    	d = (d + 3) % 4; // 좌회전
    else if (grid[r].charAt(c) == 'R')
    	d = (d + 1) % 4; // 우회전


    그냥 d를 왼쪽, 오른쪽으로 회전시킬 수 있는 방법이라면 뭐든 가능!!!! ^0^

     

     

    - d의 방향으로 또 한 칸 이동한다.
       만약, ( r, c )가 배열 밖으로 나간 경우엔 반대편으로 이동시켜준다.

    각 행과 열의 길이를 더한 다음에, 그 길이로 다시 나눈 나머지로 바꾸면
    배열을 벗어나는 좌표에 대해 처리가 가능하다.

     

    - 이동하며 거리를 증가시켰던 cntanswer(ArrayList)에 추가한다.

     

     

    - answer을 오름차순으로 정렬한 뒤, int형 배열로 바꾸어 리턴한다.

     

     

     

     

    [ 전체 코드 ]

    import java.util.ArrayList;
    
    class Solution {
        static int R, C;
        static int[] dr = { -1, 0, 1, 0 }, dc = { 0, -1, 0, 1 }; // 아래, 왼, 위, 오른
        static boolean[][][] isVisited;
    
        public int[] solution(String[] grid) {
            ArrayList<Integer> answer = new ArrayList<Integer>();
    
            R = grid.length;
            C = grid[0].length();
    
            isVisited = new boolean[R][C][4];
            for (int i = 0; i < R; i++) {
                for (int j = 0; j < C; j++) {
                    for (int d = 0; d < 4; d++) {
                        if (!isVisited[i][j][d])
                            answer.add(light(grid, i, j, d ));
                    }
                }
            }
    
            return answer.stream().sorted().mapToInt(i -> i).toArray();
        }
    
        private static int light(String[] grid, int r, int c, int d) {
            int cnt = 0; // 이동거리
    
            while (true) {
                if (isVisited[r][c][d])
                    break;
    
                cnt++;	// 거리증가
                isVisited[r][c][d] = true; // 방문처리
    
                if (grid[r].charAt(c) == 'L')
                    d = d == 0 ? 3 : d - 1; // 좌회전
                else if (grid[r].charAt(c) == 'R')
                    d = d == 3 ? 0 : d + 1; // 우회전
    
                r = (r + dr[d] + R) % R;
                c = (c + dc[d] + C) % C;
            }
    
            return cnt;
        }
    }

     

     

     

     

    [ 케이스 공유 ]

    만약 11번만 틀리신다면, 정렬을 한 후 리턴하는지 확인하시기 바랍니다!

     

     

     

     

    옼ㅋㅋ 근데, 무려 14점이나 줬다... ^0^

     

     

     

    댓글