개발블로그

백준 문제 14503 - 로봇청소기. 본문

Algorithm

백준 문제 14503 - 로봇청소기.

개발자수니 2019. 2. 9. 12:53

제가 생각한 핵심 요소는 [동쪽 방향으로 4방면 탐색하기] 입니다.

그동안 탐색을 할 때에는 방향을 신경쓰지 않아도 됐었는데, 이 문제는 동쪽 방향으로 탐색을 해야합니다.


방향을 신경쓰지 않았을 때에는 direction을 배열로 저장하고 그 크기만큼 for문을 돌면서 다음 좌표를 구하면 됐었습니다.

1
2
3
4
int[][] direction = new int[][] { { -10 }, { 01 }, { 10 }, { 0-1 } };
for (int i = 0; i < direction.length; i++) {
    //다음 좌표 구하기. 
}
cs



여기서는 현재 direction의 동쪽 방향부터 동쪽 방향의 흐름으로 탐색해야하므로 direction의 나열 순서를 맞춰야하고, 현재 direction과 일치하는 index부터 좌측이든 우측이든 동쪽 방향의 흐름대로 for문을 돌려야 했습니다.

문제에서 북-0, 동-1, 남-2, 서-3 으로 입력한다고 했으므로 해당 index에 맞게 direction을 정했습니다. 이는 index가 클수록 서쪽 방향을 의미합니다.

따라서 for문을 돌릴 때 현재 방향의 -1부터 -4까지 index를 낮추어 탐색했습니다. 이는 동쪽 방향으로 탐색함을 의미합니다.

그리고 index가 0보다 작을 경우, +4를 해주어 direction 배열의 index에 벗어나지 않도록 맞췄습니다.  

1
2
3
4
5
int[][] direction = new int[][] { { -10 }, { 01 }, { 10 }, { 0-1 } };
for (int i = curDirection - 1; i >= curDirection - 4; i--) {
    int tmpDirection = i < 0 ? i + 4 : i;
    int[] move = direction[tmpDirection];
}
cs

 


전체 코드는 다음과 같습니다.


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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package robot;
 
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
 
public class Main {
    int[][] direction = new int[][] { { -10 }, { 01 }, { 10 }, { 0-1 } };
    // 북, 동, 남, 서
 
    public static void main(String[] args) throws IOException {
        Main m = new Main();
        m.robot();
    }
 
    public void robot() throws IOException {
        /*input data 가공 start*/
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer nm = new StringTokenizer(br.readLine(), " ");
        int rows = Integer.parseInt(nm.nextToken());
        int cols = Integer.parseInt(nm.nextToken());
 
        int[][] map = new int[rows][cols];
        boolean[][] visited = new boolean[rows][cols];
 
        StringTokenizer strtInfo = new StringTokenizer(br.readLine(), " ");
        int r = Integer.parseInt(strtInfo.nextToken());
        int c = Integer.parseInt(strtInfo.nextToken());
        int startDirection = Integer.parseInt(strtInfo.nextToken());
 
        for (int i = 0; i < rows; i++) {
            StringTokenizer line = new StringTokenizer(br.readLine(), " ");
            for (int j = 0; j < cols; j++) {
                map[i][j] = Integer.parseInt(line.nextToken());
            }
        }
        /*input data 가공 end*/
        
        //1.시작점 청소
        int curR = r;
        int curC = c;
        int curDirection = startDirection;
        visited[curR][curC] = true;
        
        
        //2.청소할 다음 위치를 계속 찾는 작업.
        while (true) {
            
            boolean noWay = true//4방면 모두 청소할 수 없는 공간인지 판단하는 변수. 
            
            /*
             * 2-1. 청소를 이미 한 현 지점에서 방향을 기준으로 왼쪽부터 4방면 탐색.
             * direction을 [북,동,남,서]로 지정했고, curDirection이 direction배열의 index임.
             * 또한 index가 작아지는 방향이 왼쪽 방향임. 
             * 
            */
            for (int i = curDirection - 1; i >= curDirection - 4; i--) {
                int tmpDirection = i < 0 ? i + 4 : i;
                int[] move = direction[tmpDirection];
                int nextR = curR + move[0];
                int nextC = curC + move[1];
 
                /*
                 * 2-2. 4방면을 탐색하던 중, 이미 청소하지 않았고 빈 공간이라면 위치를 이동시키고 방향도 그 방향으로 바꿈. 
                 */
                if (map[nextR][nextC] == 0 && visited[nextR][nextC] == false) {
                    visited[nextR][nextC] = true;
                    curR = nextR;
                    curC = nextC;
                    curDirection = tmpDirection;
                    noWay = false//4방면 중 청소할 공간을 찾은 것이므로 false 지정. 
                    
                    break;
                }
            }
 
            /*
             * 2-3. 4방면 모두 청소할 수 없는 공간이라면, 
             * 방향은 그대로, 후진함. 
             * */
            if (noWay) {
                int backDirection = curDirection - 2;
                backDirection = backDirection < 0 ? backDirection + 4 : backDirection;
                int[] move = direction[backDirection];
                curR = curR + move[0];
                curC = curC + move[1];
 
                /*
                 * 2-4. 만약 후진한 곳이 벽이면 이 while문을 종료함. 
                 * */ 
                
                if (map[curR][curC] == 1) {
                    break;
                }
            }
        }
 
        // 3.visited true 인 것 갯수 세기.
        int result = 0;
        for (int i = 0; i < rows; i++) {
            for (int j = 0; j < cols; j++) {
                if (visited[i][j]) {
                    result++;
                }
            }
        }
 
        System.out.println(result);
    }
}
 
cs


'Algorithm' 카테고리의 다른 글

백준 문제 16234 - 인구 이동.  (0) 2019.03.09
Comments