Programmers

[Programmers : Java] - 공원산책

u_SZero 2023. 11. 21. 16:21

문제설명

 

범위를 벗어나거나 이동 과정에서 장애물을 마주치면 이동하지 않는 규칙!

 


 

1차 풀이

class Solution {
    public int[] solution(String[] park, String[] routes) {         // 행(w), 열(h) 수
        int w = park.length;
        int h = park[0].length();

        //출발점 설정
        int sw = 0;
        int sh = 0;
        loopOut:
        for(int i=0; i<park.length; i++)
        {
            String[] temp = park[i].split(""); 
            sh=0;
            for(int j=0; j<temp.length; j++)
            {
                if(temp[j].equals("S"))
                    break loopOut;
                else
                    sh+=1;
            }
            sw++;
        }
        
        // dir 선언 및 초기화
        int[] dir = {sw,sh};
        
        // routes 경로 확인
        for(int i=0; i<routes.length; i++)
        {
            // 공백을 기준으로 나눈 배열 생성 ("E 2" -> ["E", "2"])
            String[] dcArr = routes[i].split(" ");
            char d = dcArr[0].charAt(0);    // 'E'
            int c = Character.getNumericValue(dcArr[1].charAt(0));  // 2
            
            // 이동 과정에서의 범위 벗어남과 장애물 마주침을 확인하기 위해
            // tmp에 임시적으로 dir값 복사
            int[] tmp = dir.clone(); 
            
            // 이동 과정에서의 범위 벗어남과 장애물 마주침이 없으면 true
            // 있으면 false
            boolean flag = true;
            //System.out.println("dir[" + dir[0] + "," + dir[1] + "]");
            //System.out.println("tmp[" + tmp[0] + "," + tmp[1] + "]");
            //System.out.println("c : " + c);
            
            // E방향으로 2걸음 이동 과정 안에서 조건이 만족하는지 확인
            for(int j=1; j<=c; j++)
            {
                switch(d)
                {
                    case 'E' : tmp[1]+=1; break;
                    case 'W' : tmp[1]-=1; break;
                    case 'S' : tmp[0]+=1; break;
                    case 'N' : tmp[0]-=1; break;
                } 
                
                //System.out.println("new tmp[" + tmp[0] + "," + tmp[1] + "]");
          
                String[] tmpArr = park[tmp[0]].split("");
                
                // 범위를 벗어나거나 장애물을 맞닥뜨렸다면 false
                if((tmp[0]<0 || tmp[1]<0 || tmp[0]>w-1 || tmp[1]>h-1) || tmpArr[tmp[1]].equals("X"))
                {
                    flag = false;
                    break;
                }
            }

            // 범위 안벗어나고 장애물 안만나면 tmp의 본체인 dir 좌표 이동
            if(flag==true)
            {
                switch(d)
                {
                    case 'E' : dir[1]+=c; break;
                    case 'W' : dir[1]-=c; break;
                    case 'S' : dir[0]+=c; break;
                    case 'N' : dir[0]-=c; break;
                } 
            }
            
            //System.out.println("new dir[" + dir[0] + "," + dir[1] + "]");

        }
        return dir;
    }
}

 

프로그래머스는 문제 이해를 잘 하고 시작해야 몸이 고생을 안한다...

그냥 이동 후에 'X'가 있으면 실행 안하는 건 줄 알았는데

이동 과정에 'X'가 있어도 장애물을 넘지 못하는 것이므로 실행하지 않아야 하는 것이었다.

 

for문을 최대한 안쓰는 걸로 해서 시간 복잡도를 줄이고 싶지만

일단 문제를 해결하느라고 for문을 남발했더니 역시나 문제 풀이 실패닷!

 

오늘도 다른 분 블로그를 참조해야겠군...

 


2차 풀이

class Solution {
    public int[] solution(String[] park, String[] routes) {         
        // 행(w), 열(h) 수
        int w = park.length;
        int h = park[0].length();

        //출발점 설정
        int sw = 0;
        int sh = 0;
        for(int i=0; i<park.length; i++)
        {
            if(park[i].contains("S"))
            {
                sw = i;
                sh = park[i].indexOf("S");
            }
        }
        
        //2차원 배열로 재구성
        String[][] parkCo = new String[w][h];
        for(int i=0; i<w; i++)
        {
            String[] parkW = park[i].split("");
            for(int j=0; j<h; j++)
            {
                parkCo[i][j] = parkW[j];
            }
        }

        // routes 경로 확인
        for(int i=0; i<routes.length; i++)
        {
            // 공백을 기준으로 나눈 배열 생성 ("E 2" -> ["E", "2"])
            String[] dcArr = routes[i].split(" ");
            int c = Integer.parseInt(dcArr[1]);  // 2
            
            // 이동 과정에서의 범위 벗어남과 장애물 마주침이 없으면 true
            // 있으면 false
            boolean flag = true;

            switch(dcArr[0])
            {
                case "E" : 
                    if(sh+c>=h) break;
                    for(int j=1; j<=c; j++)
                    {
                        if(parkCo[sw][sh+j].equals("X")) 
                            flag = false;
                    }
                    if(flag==false) break;
                    sh+=c;
                    break;
                case "W" : 
                    if(sh-c<0) break;
                    for(int j=1; j<=c; j++)
                    {
                        if(parkCo[sw][sh-j].equals("X")) 
                            flag = false;
                    }
                    if(flag==false) break;
                    sh-=c;
                    break;
                case "S" : 
                    if(sw+c>=w) break;
                    for(int j=1; j<=c; j++)
                    {
                        if(parkCo[sw+j][sh].equals("X")) 
                            flag = false;
                    }
                    if(flag==false) break;
                    sw+=c;
                    break;
                case "N" : 
                    if(sw-c<0) break;
                    for(int j=1; j<=c; j++)
                    {
                        if(parkCo[sw-j][sh].equals("X")) 
                            flag = false;
                    }
                    if(flag==false) break;
                    sw-=c;
                    break;
            }
        }

        int[] dir = new int[2];
        dir[0] = sw;
        dir[1] = sh;
        return dir;
    }
}

 

블로그 글을 참고하여 해보았당....

아하... 너무나도 어렵당... 사고력을 높이는 일 쉽지 않군...

그래도 오늘했으니 익혀야지...!

화이팅...!!

 

'Programmers' 카테고리의 다른 글

[Programmers : Java] - 덧칠하기  (0) 2023.11.05
[Programmers : Java] - 추억 점수  (0) 2023.11.05
[Programmers : Java] - 달리기 경주  (0) 2023.11.02