[프로그래머스] Lv.1 공원 산책 JAVA 풀이
문제 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