https://www.acmicpc.net/problem/2234
2234번: 성곽
첫째 줄에 두 정수 N, M이 주어진다. 다음 M개의 줄에는 N개의 정수로 벽에 대한 정보가 주어진다. 벽에 대한 정보는 한 정수로 주어지는데, 서쪽에 벽이 있을 때는 1을, 북쪽에 벽이 있을 때는 2를,
www.acmicpc.net
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.Queue;
import java.util.StringTokenizer;
public class Main {
static int N, M, max = 0;
static int[][] map;
static boolean[][] visited;
// 서북동남 좌상우하
static int[] dr = { 0, -1, 0, 1 };
static int[] dc = { -1, 0, 1, 0 };
public static void main(String[] args) throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringBuilder sb = new StringBuilder();
StringTokenizer st = new StringTokenizer(br.readLine());
N = Integer.parseInt(st.nextToken());
M = Integer.parseInt(st.nextToken());
map = new int[M][N];
visited = new boolean[M][N];
// map 입력받기
for (int r = 0; r < M; r++) {
st = new StringTokenizer(br.readLine());
for (int c = 0; c < N; c++) {
map[r][c] = Integer.parseInt(st.nextToken());
}
}
// 1. 이 성에 있는 방의 개수
// 2. 가장 넓은 방의 넓이
int room = 0;
for (int r = 0; r < M; r++) {
for (int c = 0; c < N; c++) {
if (!visited[r][c]) {
bfs(r, c);
room++;
}
}
}
sb.append(room).append("\n").append(max).append("\n");
// 3. 하나의 벽을 제거하여 얻을 수 있는 가장 넓은 방의 크기
for (int r = 0; r < M; r++) {
for (int c = 0; c < N; c++) {
// 사방탐색
for (int bit = 1; bit <= 8; bit <<= 1) {
// 현재 방향으로 갈 수 있는 경우
// 0인 경우: bit 방향에 벽 없음
// 0이 아닌 경우: bit 방향에 벽 있음
if ((map[r][c] & bit) != 0) {
visited = new boolean[M][N];
// 벽 제거
map[r][c] -= bit;
bfs(r, c);
// 다시 벽 세우기
map[r][c] += bit;
}
}
}
}
sb.append(max);
System.out.println(sb);
}
private static void bfs(int r, int c) {
Queue<int[]> q = new LinkedList<>();
q.add(new int[] { r, c });
visited[r][c] = true;
int cRoom = 1, cr, cc, nr, nc, bit, curr[];
while (!q.isEmpty()) {
curr = q.poll();
cr = curr[0];
cc = curr[1];
bit = 1;
for (int dir = 0; dir < 4; dir++) {
if ((map[cr][cc] & bit) == 0) {
nr = cr + dr[dir];
nc = cc + dc[dir];
// 경계 안에 있고 아직 방문하지 않은 경우
if ((nr >= 0 && nr < M && nc >= 0 && nc < N) && !visited[nr][nc]) {
// 방의 개수 + 1
cRoom++;
visited[nr][nc] = true;
q.add(new int[] { nr, nc });
}
}
// 1 2 4 8
bit <<= 1;
}
}
// 최댓값과 현재 방의 개수 비교
max = Math.max(max, cRoom);
}
}
'Baekjoon Online Judge > Java' 카테고리의 다른 글
[Baekjoon Online Judge] 16956 - 늑대와 양 / Java (0) | 2021.10.26 |
---|---|
[Baekjoon Online Judge] 17471 - 게리맨더링 / Java (0) | 2021.10.07 |
[Baekjoon Online Judge] 4179 - 불! / Java (0) | 2021.10.01 |
[Baekjoon Online Judge] 1194 - 달이 차오른다, 가자. / Java (0) | 2021.09.29 |
[Baekjoon Online Judge] 4485 - 녹색 옷 입은 애가 젤다지? / Java (0) | 2021.09.29 |