본문 바로가기

Algorithm

DFS를 Stack을 이용해서 풀어보자.

반응형

https://www.acmicpc.net/problem/2667

 

2667번: 단지번호붙이기

<그림 1>과 같이 정사각형 모양의 지도가 있다. 1은 집이 있는 곳을, 0은 집이 없는 곳을 나타낸다. 철수는 이 지도를 가지고 연결된 집들의 모임인 단지를 정의하고, 단지에 번호를 붙이려 한다. 여기서 연결되었다는 것은 어떤 집이 좌우, 혹은 아래위로 다른 집이 있는 경우를 말한다. 대각선상에 집이 있는 경우는 연결된 것이 아니다. <그림 2>는 <그림 1>을 단지별로 번호를 붙인 것이다. 지도를 입력하여 단지수를 출력하고, 각 단지에 속하는 집의 수

www.acmicpc.net

 

재귀함수를 이용하는게 아닌  Stack구조를 이용하여서 문제를 풀어보았다.

기존 DFS 탐색은 Stack 많은 값이 쌓이면 스택오버플로우를 일으킨다. 하지만 Stack을 사용하여 DFS를 구현하면 적은 메모리로 깊이 우선탐색을 구현할수가 있다.

 

일단 Stack은 두가지를 이용한다. 첫번째는 Stack은 i j 좌표값을 저장한다. 두번째는 Stackd 는 어느방향까지 탐색했었는지를 저장한다.

 

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
 
 
public class 두더지굴 {
 
    public static void main(String[] args) throws NumberFormatException, IOException {
 
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
 
        int N = Integer.parseInt(br.readLine());
 
        int Map[][] = new int[N][N];
        boolean check[][] = new boolean[N][N];
        int Stack[] = new int[N * N];
        int Stackd[] = new int[N * N];
        int sSize = -1;
 
        for (int i = 0; i < N; i++) {
            char[] c = br.readLine().toCharArray();
            for (int j = 0; j < N; j++) {
                Map[i][j] = c[j] - '0';
            }
        }
 
        ArrayList<Integer> cnt = new ArrayList<>();
        int thisCnt = 0;
        int dy[] = { 00-11 };
        int dx[] = { 1-100 };
 
        for (int i = 0; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if (Map[i][j] == 1 && check[i][j] == false) {
                    thisCnt = 0;
                    Stack[++sSize] = i * N + j;
                    Stackd[sSize] = 0;
                    while (sSize >= 0) {
                        int y = Stack[sSize] / N;
                        int x = Stack[sSize] % N;
                        if (!check[y][x]) {
                            thisCnt++;
                            check[y][x] = true;
                        }
 
                        boolean thisCheck = true;
                        for (int d = Stackd[sSize]; d < 4; d++) {
                            int ny = y + dy[d];
                            int nx = x + dx[d];
 
                            if (ny < 0 || nx < 0 || ny >= N || nx >= N)
                                continue;
                            if (Map[ny][nx] == 0)
                                continue;
                            if (check[ny][nx])
                                continue;
                            Stackd[sSize] = d+1;
                            Stack[++sSize] = ny * N + nx;
                            Stackd[sSize] = 0;
                            
                            thisCheck = false;
                            break;
                        }
                        if (thisCheck) {
                            --sSize;
                        }
 
                    }
                    cnt.add(thisCnt);
 
                }
 
            }
        }
 
        System.out.println(cnt.size());
        Collections.sort(cnt);
        for (int i = 0; i < cnt.size(); i++) {
            System.out.println(cnt.get(i));
        }
 
    }
 
}
 
http://colorscripter.com/info#e" target="_blank" style="color:#4f4f4ftext-decoration:none">Colored by Color Scripter
반응형

'Algorithm' 카테고리의 다른 글

세그먼트 트리  (0) 2020.02.27
트리의 지름  (0) 2020.02.24
유니온 파인드 : JAVA  (0) 2020.02.12
정렬  (0) 2020.02.11
특정 Map 회전 시키기  (0) 2020.02.07