포스트

토마토(7569)

토마토(7569)

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
113
114
115
116
117
import java.io.*;
import java.util.*;

public class Main {
  
  static Deque<Node> dq = new ArrayDeque<>();
  static int m, n, h;
  static int[][][] to;
  
  public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out));
    StringBuilder sb = new StringBuilder();
  
    StringTokenizer st =  new StringTokenizer(br.readLine());
    
    m = Integer.parseInt(st.nextToken());
    n = Integer.parseInt(st.nextToken());
    h = Integer.parseInt(st.nextToken());
    
    // BFS에서 for문 순회를 위해 여유 공간 +2
    to = new int[h+2][n+2][m+2];
    
    // 모든 값을 -1로 초기화
    for(int z = 0; z <= h+1; z++) {
      for(int y = 0; y <= n+1; y++) {
        for(int x = 0; x <= m+1; x++) {
          to[z][y][x] = -1;
        }
      }
    }
  
    Node node;
    
    // 입력받은 값의 범위
    for(int z = 1; z <= h; z++) {
      for(int y = 1; y <= n; y++) {
        st =  new StringTokenizer(br.readLine());
        
        for(int x = 1; x <= m; x++) {
          int v = Integer.parseInt(st.nextToken());
          to[z][y][x] = v;
          if(v == 1) {
            node = new Node(z, y, x);
            dq.offerFirst(node);
          }
        }
      }
    }
    
    BFS();
    
    int max = 0;
    boolean flag = false;
    
    for(int z = 1; z <= h; z++) {
      for(int y = 1; y <= n; y++) {
        for(int x = 1; x <= m; x++) {
          if(to[z][y][x] == 0) {
            flag = true;
            break;
          }
          
          max = Math.max(max, to[z][y][x]);
        }
        
        if(flag) break;
      }
      
      if(flag) break;
    }
    
    if(flag) sb.append(-1);
    else sb.append(max-1);

    bw.write(sb.toString());
    bw.flush();
    bw.close();
    br.close();
  }
  
  public static void BFS() {
    
    int[] zArr = {1, -1, 0, 0, 0, 0};
    int[] yArr = {0, 0, 1, -1, 0, 0};
    int[] xArr = {0, 0, 0, 0, 1, -1};
    
    while(!dq.isEmpty()) {
      Node node = dq.pollLast();
      
      int z = node.z;
      int y = node.y;
      int x = node.x;
      
      for(int i = 0; i < 6; i++) {
        // 순서 : 상층, 하층, 아래, 위, 우, 좌
        if(to[z + zArr[i]][y + yArr[i]][x + xArr[i]] == 0) {
          node = new Node(z + zArr[i], y + yArr[i], x + xArr[i]);
          dq.offerFirst(node);
          to[z + zArr[i]][y + yArr[i]][x + xArr[i]] = to[z][y][x] + 1;
        }
      }
    }
  }
  
  public static class Node{
    int z;
    int y;
    int x;
    
    public Node(int z, int y, int x){
      this.z = z;
      this.y = y;
      this.x = x;
    }
  }
}
  1. 기존에 풀었던 토마토(7576) 에서 층만 추가된 문제이다
  2. 상하좌우 4개의 경우를 순회하는 것 + 위아래 2개를 추가하여 순회하도록 구현하였다.
1
2
3
- 성공
- 메모리 : 100008 KB
- 시간 : 764 ms

보안점

  1. BFS의 순회하는 코드가 길어져 다른 사람의 풀이를 봐왔던 for문을 이용하여 순회하는 것을 생각하여 풀어보았는데
  2. 배열을 3개를 만들어 각 각의 요소에 더하는 것으로 했다
  3. 코드의 길이는 짧아졌지만 각 배열의 수를 더하는 것을 하다보니 코드가 깔끔하지는 않았다.
  4. 순회를 하는 배열을 2차배열로 만들고, 값으로 3개씩 넣는게 좋아보였다.
    • arr[6][3] = { {1, 0, 0}, {-1, 0, 0}, {0, 1, 0}, {0, -1, 0}, {0, 0, 1}, {0, 0, -1} }