728x90
문제
16946번: 벽 부수고 이동하기 4
N×M의 행렬로 표현되는 맵이 있다. 맵에서 0은 이동할 수 있는 곳을 나타내고, 1은 이동할 수 없는 벽이 있는 곳을 나타낸다. 한 칸에서 다른 칸으로 이동하려면, 두 칸이 인접해야 한다. 두 칸이
www.acmicpc.net
접근 방식
맵의 최대 크기가 1000 * 1000이기 때문에
매번 벽을 기준으로 BFS나 DFS를 이용해 탐색하면 시간초과가 발생한다.
그래서 0을 기준으로 각 구역의 크기를 계산한 후에
1을 기준으로 상하좌우로 맞닿은 구역의 크기를 더해주면 되는데
이때 중복이 있을 수 있기 때문에 Set을 사용해서 처리해 주면 된다.
예를 들어 현재 벽과 맞닿은 구역이 1, 1, 2, 3 구역이라면
1 구역은 한 번만 계산하면 되기 때문에 중복을 처리해
1, 2, 3 구역의 크기를 한 번씩만 계산해 주면 된다.
풀이
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
String[] input = br.readLine().split(" ");
StringBuilder sb = new StringBuilder();
int n = Integer.parseInt(input[0]);
int m = Integer.parseInt(input[1]);
int[] dx = {-1, 1, 0, 0};
int[] dy = {0, 0, -1, 1};
int[][] map = new int[n][m];
int[][] isVisited = new int[n][m];
Queue<Pair> q = new ArrayDeque<>();
for (int i = 0; i < n; i++) {
input = br.readLine().split("");
for (int j = 0; j < m; j++) {
map[i][j] = Integer.parseInt(input[j]) * -1;
}
}
Map<Integer, Integer> counts = new HashMap<>();
int num = 1;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (map[i][j] == -1) continue;
if (isVisited[i][j] != 0) continue;
int cnt = 1;
q.offer(new Pair(i, j));
isVisited[i][j] = num;
while (!q.isEmpty()) {
Pair cur = q.poll();
for (int dir = 0; dir < 4; dir++) {
int nx = cur.x + dx[dir];
int ny = cur.y + dy[dir];
if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
if (isVisited[nx][ny] != 0 || map[nx][ny] == -1) continue;
cnt++;
isVisited[nx][ny] = num;
q.offer(new Pair(nx, ny));
}
}
counts.put(num++, cnt);
}
}
Set<Integer> set = new HashSet<>();
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (map[i][j] == 0) {
sb.append(0);
continue;
}
int cnt = 1;
for (int dir = 0; dir < 4; dir++) {
int nx = i + dx[dir];
int ny = j + dy[dir];
if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
if (map[nx][ny] == -1) continue;
set.add(isVisited[nx][ny]);
}
for (int c : set) cnt += counts.get(c);
set.clear();
sb.append(cnt % 10);
}
sb.append("\n");
}
System.out.println(sb);
}
static class Pair {
int x, y;
public Pair(int x, int y) {
this.x = x;
this.y = y;
}
}
}
'Java > Algorithms' 카테고리의 다른 글
[백준] 18352번 : 특정 거리의 도시 찾기 (0) | 2024.04.18 |
---|---|
[백준] 1202번 : 보석 도둑 (0) | 2024.04.16 |
[백준] 2239번 : 스도쿠 (0) | 2024.04.13 |
[백준] 15659번 : 연산자 끼워넣기 (3) (0) | 2024.04.12 |
[백준] 1759번 : 암호 만들기 (0) | 2024.04.11 |