본문 바로가기
Programmers/Lv.1

[프로그래머스] Lv.1 공원 산책 JAVA 풀이

by Poorm 푸름 2024. 6. 28.

문제 Lv.1 공원 산책 (방향 탐색 시뮬레이션)

 

 :  지나다니는 길 O 장애물 X

    ["방향거리", "방향거리"..]

 

    "E 5" = 현재 위치에서 동쪽으로 5칸 이동했다는 의미

 

    공원의 가로 길이가 W, 세로 길이가 H

 

    공원을 나타내는 문자열 배열 park

    명령이 담긴 문자열 배열 routes

 

  • 3 ≤ park[i]의 길이 ≤ 50
    • S : 시작 지점 (1개) 
    • O : 이동 가능한 통로
    • X : 장애물
  • 1 ≤ routes의 길이 ≤ 50
    • 수행할 명령어
    • routes의 원소는 "op n"과 같은 구조 (op는 이동할 방향, n은 이동할 칸의 수)
      • N : 북 이동 / S : 남 이동 / W : 서 이동 / E : 동 이동
    • 1 ≤ n ≤ 9

 

 

[과정]

 

- 2차원 배열 헷갈리지 말자!! -

 

arr[행][열] 발음하는 순서대로 생각하면 된다 (행의 인덱스 / 열의 인덱스)

  • 다만 인덱스는 세로줄을 보고 판단 의 인덱스는 가로줄을 보고 판단

  • 행의 개수 = 세로로 나열된 원소의 개수
    열의 개수 = 가로로 나열된 원소의 개수

    단순히 행은 가로줄을 의미하니까 가로줄의 원소의 개수와 같다고 생각해선 안된다!

 

x이동과 y이동은 좌표가 아닌 배열의 형식으로 생각한다

 

char[][] arr = {
    {'O', 'S', 'O'},
    {'O', 'X', 'O'},
    {'O', 'O', 'O'}
};

 

여기서 S의 위치는 좌표형식으로 본다면 높이가 바뀐 것이 아니기 때문에 (1,0) 이다 

하지만 배열의 형식으로 본다면 0번째 행의 1번째 열이므로 arr[1][0]이 맞다

고로 x를 가로의 이동이 아닌 행의 이동 (세로이동)으로 생각하고

y를 세로의 이동이 아닌 열의 이동 (가로이동)으로 생각한다

 

 

1. 좌표이동

  • E = 우로 이동 = 열 변경 (y++)
  • W = 좌로 이동 = 열 변경 (y--)
  • N = 상으로 이동 = 행 변경 (x--)
  • S = 하로 이동 = 행 변경 (x++)

2. 이동은 for문을 거쳐서

  • 이동할 때 그 좌표로 바로 가는게 아니다
  • 그 좌표까지 거쳐가는 노드들도 계산을 해줘야하기 때문에 for문을 걸어준다

 

3. 조건 걸기

  • 하나라도 통과 못하면 break 걸어버려~~
  • 하지만 해당코드는 참이 되지 않는 경우부터 먼저 쓴다 (||연산자 사용)
    • nx < 0 || ny < 0 범위를 벗어날 경우 
    • ny >= park[0].length() || nx >= park.length 범위를 벗어날 경우
    • || arr[nx][ny] == 'X' 장애물일 경우
    • break 하고 바로 종료 애초에 시작불가

 

4. 마지막 연산에서만 시작지점 갱신

  • 모두 다 이동했을 때만 시작지점을 현지점으로 갱신

 

 

[함수 1] String.toCharArray()

  • String(문자열)을 한 글자씩 쪼개서 char형 배열에 집어넣어주는 친절한 메소드
  • arr[i]=park[i].toCharArray()라고 할 경우 자동으로 2차원 배열 생성

 

[코드]

import java.io.*;
import java.util.*;

class Solution {
    public int[] solution(String[] park, String[] routes) {
        char arr[][] = new char[park.length][park[0].length()];
        int start[]= new int[2];
        
        for(int i=0;i<park.length;i++){
            arr[i]=park[i].toCharArray();
            for(int j=0;j<park[0].length();j++){
                if(arr[i][j]=='S'){
                    start[0]=i;
                    start[1]=j;
                }
            }
        }
        
        for(String r:routes){
            String[] s = r.split(" ");
            int num = Integer.parseInt(s[1]); 
            int nx = start[0];
            int ny = start[1];
            for(int i=0;i<num;i++){
                switch(s[0]){
                    case "E": ny++; break;
                    case "S": nx++; break;
                    case "W": ny--; break;
                    case "N": nx--; break;
                }
                
                if (nx < 0 || nx >= park.length || ny < 0 || ny >= park[0].length() || arr[nx][ny] == 'X') {
                    break;
                }
                
                 if (i == num - 1) {
                    start[0] = nx;
                    start[1] = ny;
                }
            }
        }
        return start;
    }
}

 

 : public int[] solution(String[] park, String[] routes) {  park랑 routes 입력받기
        char arr[][] = new char[park.length][park[0].length()];  [행개수][열개수]
        int start[] =new int[2];  출력 배열
        
        for(int i=0;i<park.length; i++){
            arr[i]=park[i].toCharArray();  i행마다 park 한묶음씩 집어넣고 j열에 묶음 쪼개기
            for(int j=0; j<park[0].length();j++){  한묶음 안의 원소개수 만큼 열 만들기
                if(arr[i][j]=='S'){  S라고 하면 시작지점
                    start[0]=i;  행
                    start[1]=j;  열
                }
            }
        }
       
        for(String r : routes){  입력받은 routes 배열 한묶음씩 보기
            String s = route.split(" ");  방향
            int num = Integer.parseInt(s[1]);  움직일 칸 개수
            int nx = start[0];  시작지점으로 nx 초기화
            int ny = start[1];   시작지점으로 ny 초기화
            
            for(int j=0; j<num; j++){  routes의 한묶음 안의 원소 다 살펴보기
                switch(s[0]){  방향이 무엇인지 보고 그에 맞는 명령어 대입
                    case "E": ny++; break;  열 이동 (보이는건 가로 변화)
                    case "W": ny--; break;   열 이동 (보이는건 가로 변화)
                    case "N": nx--; break;  행 이동 (보이는건 세로 변화)
                    case "S": nx++; break;   이동 (보이는건 세로 변화)
                }
                 if (nx < 0 || ny >= park[0].length() || ny < 0 || nx >= park.length || arr[nx][ny] == 'X') {
                    break;  더 갈 것도 없이 바로 중단
                }
                
                if (j == move - 1) {  for문 마지막 순간에 뽑아내기
                    start[0] = nx;  시작지점을 지금의 지점으로 갱신
                    start[1] = ny;  시작지점을 지금의 지점으로 갱신
                }
            }
        }
        return start;  결과 출력
    }
}

 

 


  

https://school.programmers.co.kr/learn/courses/30/lessons/172928?language=java

 

프로그래머스

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

programmers.co.kr