출처 : https://www.acmicpc.net/problem/1113
풀이 방법
경계를 판단하기가 어려웠고 높이가 1~9이기 때문에 범위가 매우 작다는 점을 이용해서 가장 작은 높이에서 가장 큰 높이 직전까지 1씩 증가해 가면서 풀이하는 방법으로 풀이했다.
(한 번에 계산은 안됨)
테두리일 경우, 넘쳐나게 되므로 테두리일 땐, 높이를 증가시키면 안 된다.
이를 위해 visited 값을 2로 설정한 것은 높이를 증가시키지 않았다.
또한 중복해서 더해지는 경우도 방지해야 하므로 한 번 높이를 증가시킨 경우 visited값을 +1을 해주어서 중복 계산을 방지해야 한다.
import java.io.*;
import java.util.*;
public class Main {
static int n, m;
static int[][] pool, visited;
static int maxN, minN, ans = 0;
static int[] dy = {0, 0, 1, -1};
static int[] dx = {1, -1, 0, 0};
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st;
st = new StringTokenizer(br.readLine());
n = Integer.parseInt(st.nextToken());
m = Integer.parseInt(st.nextToken());
pool = new int[n][m];
visited = new int[n][m];
maxN = 0;
minN = 9;
for (int i = 0; i < n; i++) {
String str = br.readLine();
for (int j = 0;j < str.length();j++) {
pool[i][j] = str.charAt(j) - '0';
maxN = Math.max(maxN, pool[i][j]);
minN = Math.min(minN, pool[i][j]);
}
}
// 각 수에서 bfs를 돌리며, 채울 수 있는지 없는지 판별한다 수가 된다면 큐에 넣고 bfs 만약 돌다 끝에 닿으면 다 패기한다.
for (int i = minN; i < maxN; i++) {
// visited 초기화 하기
initViisted();
for (int j = 1; j < n-1; j++) {
for (int k = 1; k < m-1; k++) {
if (visited[j][k] != 0) continue;
if (pool[j][k] != i) continue; // i가 아니면 패스
bfs(j, k, i);
}
}
}
System.out.println(ans);
}
public static void bfs(int y, int x, int h) {
Queue<int[]> q = new LinkedList<>();
q.offer(new int[] {y, x});
visited[y][x] = 1;
boolean flag = true;
while(!q.isEmpty()) {
int[] cur = q.poll();
for (int i = 0;i < 4;i++) {
int ny = cur[0] + dy[i];
int nx = cur[1] + dx[i];
if (ny < 0 || ny >= n || nx < 0 || nx >= m) continue;
if (visited[ny][nx] == 1) continue;
if (pool[ny][nx] < h) flag = false;
// 테두리라면 종료해야한다.
if ((ny == 0 || nx == 0 || ny == n-1 || nx == m-1) && pool[ny][nx] <= h) {
flag = false;
continue;
}
// 주변에 나보다 작은 것이 있지만 처리가 되지 않은 것이 있다면 종료해야한다.
if (pool[ny][nx] != h) continue;
q.offer(new int[] {ny, nx});
visited[ny][nx] = 1;
}
}
if (flag) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (visited[i][j] == 1) {
pool[i][j]++;
ans++;
visited[i][j]++; // 중복해서 더해지지 않도록 하는 함수
}
}
}
}
else { // flag가 false일 때
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (visited[i][j] == 1) {
visited[i][j] = 2;
}
}
}
}
return ;
}
public static void initViisted() {
for (int i = 0; i < n; i++) {
Arrays.fill(visited[i], 0);
}
}
}
'Algorithm' 카테고리의 다른 글
[백준] 외판원 순회 2098번 (java) 비트마스킹 + dp (1) | 2025.06.15 |
---|---|
[백준] 우주 탐사선 17182번 (java) 플로이드 워샬, 순열 (1) | 2025.06.15 |
[백준] 닭싸움 팀 정하기 1765번 Java (1) | 2025.06.13 |
[프로그래머스] 홀짝트리 (java) 그래프 (1) | 2025.06.08 |
[백준] 불켜기 11967번 (java) (0) | 2025.06.08 |