코테/코드트리

[코드트리/NOVICE MID] 작은 구슬의 이동 (JAVA)

imname1am 2023. 11. 3. 10:42
반응형

🔺 문제

 

코드트리 | 코딩테스트 준비를 위한 알고리즘 정석

국가대표가 만든 코딩 공부의 가이드북 코딩 왕초보부터 꿈의 직장 코테 합격까지, 국가대표가 엄선한 커리큘럼으로 준비해보세요.

www.codetree.ai

 

 

🔺 코드

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import java.util.*;
import java.io.*;
 
public class Main {
    static int[] dx = {0,1,-1,0};   // 🔔 동남북서 (행과 열 기준)
    static int[] dy = {1,0,0,-1};
 
    static int N, T, R, C;
    static char dir;
    static int[][] map;
 
    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(br.readLine(), " ");
 
        N = Integer.parseInt(st.nextToken());   // 격자 크기
        T = Integer.parseInt(st.nextToken());   // 시간
        map = new int[N + 1][N + 1];
 
        st = new StringTokenizer(br.readLine(), " ");
        R = Integer.parseInt(st.nextToken());
        C = Integer.parseInt(st.nextToken());
        dir = st.nextToken().charAt(0);   // 방향
 
        int moveDir = getDir(dir);
        while(T --> 0) {
            int nx = R + dx[moveDir];
            int ny = C + dy[moveDir];
 
            if(!inRange(nx, ny)) {    // 격자 벗어나면 방향 전환
                moveDir = 3 - moveDir;
            }
            else {  // 이동
                R += dx[moveDir];
                C += dy[moveDir];
            }
        }
 
        System.out.println(R + " " + C);
    }
 
    // 이동 방향 가져오는 함수
    private static int getDir(char c) {
        if(c == 'R')    return 0;
        else if(c == 'D')   return 1;
        else if(c == 'U')   return 2;
        else                return 3;
    }
 
    // 범위 내에 있는지 확인하는 함수
    private static boolean inRange(int x, int y) {
        return (1 <= x && x <= N && 1 <= y && y <= N);
    }
}
cs

 

 

 

🧩  해결 아이디어

• dx/dy techinque

1. 값들을 입력받는다.

2. 남은 시간만큼 이동 방향으로 이동하려 할 때 격자를 벗어나면, 방향을 전환하며 시간이 1초 소요된다. (moveDir = 3 - moveDir)

3. 격자를 벗어나지 않는다면, 이동 방향으로 이동하며 시간이 1초 소요된다.

 

- dx, dy 배열을 "행과 열로 생각"해 동남북서 순서로 저장한다.

- 방향 전환 시, 3에서 해당 방향을 뺸 값으로 바꾸면 방향 전환이 이뤄진다.

 

예를 들어 현재 이동 방향이 동쪽(0)인 상태로 격자 맨 끝에 닿았다고 할 때,

방향 전환하면 서쪽(3)이 되어야하므로 3-0 하는 것이다. 그러면 배열의 3번째 인덱스인 서쪽으로 방향이 전한된다.

 

 


🔺 다른 풀이들

- dx/dy 배열 값을 일반적으로(?) 생성해두시고,

격자 벗어나면 방향 전환을 dir  = (dir + 2) % 4;하고 continue;로 다음 차례로 돌아가게 했다.

static int[] dx = {0, 1, 0, -1};
static int[] dy = {1, 0, -1, 0};

.
.
.

int nx, ny;
for(int t = 0 ; t < T ; t++){
    nx = R + dx[dir];
    ny = C + dy[dir];

    if(!isRange(nx, ny)){	// 격자 벗어나면 방향 전환
        dir = (dir + 2) % 4;
        continue;
    }

    // 격자 내에 있으면 이동
    R = nx;
    C = ny;
}

 


💬 느낀 점

안 그래도 방향 전환하는 문제 잘 못 풀어서 언젠가 꼭 정리해야지 했는데 잘 만났다ㅠ

 

머릿속으로 뭔가 생각이 빨리 진행되지 않아서 구현까지도 시간이 오래 걸렸었다.

나는 평소 dx dy를 써야할 문제를 풀 때, dx dy를 행과 열 기준으로 생각하지 않고 동서남북 방향으로 생각했고

값을 고정시켜뒀었다.

그런데 이러면 방향 전환하고 이럴 때 뭔가 뇌정지가 와서 문제 해결까지 꽤 시간이 걸렸던 것이다...!! ㄴㅇㄱ

 

아예 행과 열로 생각해서 dx dy를 목적에 맞게 순서를 바꿔서 값을 설정해두고

이렇게 방향 전환하는 기술도 있구나 싶었다...

 

담엔 집중해서 더 빠르게 푸는 걸로!

 

 

1회독 2회독 3회독 4회독 5회독
V        

(참고)

✔ 코드트리 dx/dy technique) 조건에 따라 방향이 변하는 경우

 

반응형