정사각형의 치즈가 인풋으로 주어지고, 각 칸마다 숫자가 있다.
각 시간마다 시간과 일치하는 숫자의 칸을 먹는다.
그 과정에서 남은 치즈들의 덩어리가 생기는데, 전체 치즈를 다 먹는 과정에서 생기는 치즈 덩어리의 최댓값을 구해라!
이 문제를 보자마자 '격자 그래프'가 떠올랐다.
그리고, 덩어리들을 묶어야하니까 BFS로 찾는 방식을 택했다.
BFS로 아직 남아있는 덩어리들을 방문처리를 하고, 다 방문했으면 덩어리 개수를 1 올리는 방식!
import java.io.*;
import java.util.*;
public class swea_7733_치즈도둑 {
static int[][] cheese;
static boolean[][] visited;
static int res;
static int N;
static int[] dr = {-1, 1, 0, 0};
static int[] dc = {0, 0, -1, 1};
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
int T = Integer.parseInt(br.readLine()); // 치즈 배열 크기
for (int tc = 1; tc <= T; tc++) {
N = Integer.parseInt(br.readLine());
cheese = new int[N][N]; // 치즈 원본 생성
int X = 0;
res = 1;
for (int i = 0; i < N; i++) {
StringTokenizer st = new StringTokenizer(br.readLine(), " ");
for (int j = 0; j < N; j++) {
cheese[i][j] = Integer.parseInt(st.nextToken());
if (cheese[i][j] > X) X = cheese[i][j];
}
}
int cnt = 1;
while (cnt <= X) {
visited = new boolean[N][N];
int combine = 0;
for (int r = 0; r < N; r++) {
for (int c = 0; c < N; c++) {
if (cheese[r][c] > cnt && !visited[r][c]) {
// System.out.println("cheese[r][c] <= cnt && !visited[r][c]");
Node n = new Node(r, c);
bfs(n, cnt); // bfs돌리면서 visited 처리하고 다 돌면 카운트처리
combine++;
}
}
}
// 치즈덩어리 개수 비교
if (res < combine) {
res = combine;
// System.out.println("res < combine");
}
cnt++;
}
sb.append("#").append(tc).append(" ").append(res).append("\n");
} // end of tc
System.out.println(sb.toString());
} // end of main
public static class Node {
int x;
int y;
public Node(int x, int y) {
this.x = x;
this.y = y;
}
}
static void bfs(Node n, int cnt) {
// 방문을 기록할 노트
Queue<Node> q = new ArrayDeque<>();
// 시작 노드 집어 넣는다.
q.offer(n);
int r = n.x;
int c = n.y;
// 시작노드 방문처리
visited[r][c] = true;
while(!q.isEmpty()) {
Node next = q.poll();
for (int i = 0; i < 4; i++) {
int nr = next.x+dr[i];
int nc = next.y+dc[i];
// 범위 가두기
if (nr >= 0 && nr < N && nc >= 0 && nc < N && cheese[nr][nc] > cnt && !visited[nr][nc]) {
q.offer(new Node(nr, nc));
visited[nr][nc] = true;
}
}
}
}
} // end of class
🌟 전부다 1일때를 놓쳤다. -> 모든 덩어리는 최소 1개이므로 덩어리의 초기값은 1로 초기화했어야 한다..
🌟 res를 초기화 하는걸 놓쳤다. -> static 변수들은 항상 테케안에서 초기화하는걸 명심할 것!
🌟 제미나이의 테케를 믿지말것. 제미나이한테 테케 생성해달라했다가 제미나이가 숫자 잘못센거때문에 20분 넘게 코드를 계속 고민했다...
🌟 문제를 처음 봤을 때, 시간복잡도부터 계산했다.
N은 최대 100, X값도 최대 100이니까 이 문제는 O(N^2 * X) 안에 다 돌려야한다고 판단해서 코드를 짤때도 이를 생각하면서 짜서 시간초과가 안났다!! (이건 잘한듯 ㅎㅎ) 다음에도 이래야한다!