BFS/DFS를 통해 구역을 나누는 문제이다.
처음에는 양의 수
와 늑대의 수
를 저장한 Section
이라는 클래스를 만들어
ArrayList<Section>
에 저장한 후,
마지막에 결과를 집계하려 했으나, 굳이 클래스를 만들 필요는 없었다.
마당의 구조
에 대한 입력은 char[][]
로 받았다.
배열을 순회하며, 아직 방문하지 않은 칸이 발견되면,
방문하지 않은 주변의 칸들을 DFS로 방문한다.
이후, 해당 구역에서 센 양의 수
와 늑대의 수
를 확인하고 결과값에 반영한다.
private static void observe() {
visited = new boolean[R][C];
for (int r=0; r<R; r++) {
for (int c=0; c<C; c++) {
// 현재 구역에 대한 양의 수와 늑대의 수를 초기화
currentSectionSheepCnt = 0;
currentSectionWolvesCnt = 0;
// 방문하지 않은 칸을 발견하면 주변 칸들을 연쇄적으로 탐색
if (map[r][c] != WALL && !visited[r][c]) {
visitNearby(r, c);
}
// 현재 구역의 늑대의 수와 양의 수를 비교해 결과값에 반영
if (currentSectionWolvesCnt >= currentSectionSheepCnt) {
resultWolvesCnt += currentSectionWolvesCnt;
}
else {
resultSheepCnt += currentSectionSheepCnt;
}
}
}
}
해당 칸을 방문 처리,
해당 칸에 늑대가 있다면 현재 구역에 대한 늑대의 수를 증가,
양이 있다면 현재 구역에 대한 양의 수를 증가,
주변의 방문하지 않은 칸들을 추가로 방문.
private static int[] dr = new int[] {-1, 0, 1, 0};
private static int[] dc = new int[] {0, 1, 0, -1};
private static void visitNearby(int r, int c) {
visited[r][c] = true;
if (map[r][c] == WOLF) {
currentSectionWolvesCnt++;
}
else if (map[r][c] == SHEEP) {
currentSectionSheepCnt++;
}
for (int dir = 0; dir < 4; dir++) {
int nextR = r + dr[dir];
int nextC = c + dc[dir];
if (nextR < 0 || nextR == R || nextC < 0 || nextC == C) {
continue;
}
if (map[nextR][nextC] != WALL && !visited[nextR][nextC]) {
visitNearby(nextR, nextC);
}
}
}
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class _3184 {
private static final char WALL = '#';
private static final char WOLF = 'v';
private static final char SHEEP = 'o';
private static final char EMPTY = '.';
private static int R, C;
private static char[][] map;
private static boolean[][] visited;
private static int currentSectionSheepCnt;
private static int currentSectionWolvesCnt;
private static int resultSheepCnt;
private static int resultWolvesCnt;
public static void main(String[] args) throws IOException {
input();
observe();
System.out.printf("%d %d\n", resultSheepCnt, resultWolvesCnt);
}
private static void input() throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
StringTokenizer st = new StringTokenizer(br.readLine());
R = Integer.parseInt(st.nextToken());
C = Integer.parseInt(st.nextToken());
map = new char[R][C];
for (int r=0; r<R; r++) {
String str = br.readLine();
for (int c=0; c<C; c++) {
map[r][c] = str.charAt(c);
}
}
}
private static void observe() {
visited = new boolean[R][C];
for (int r=0; r<R; r++) {
for (int c=0; c<C; c++) {
currentSectionSheepCnt = 0;
currentSectionWolvesCnt = 0;
if (map[r][c] != WALL && !visited[r][c]) {
visitNearby(r, c);
}
if (currentSectionWolvesCnt >= currentSectionSheepCnt) {
resultWolvesCnt += currentSectionWolvesCnt;
}
else {
resultSheepCnt += currentSectionSheepCnt;
}
}
}
}
private static int[] dr = new int[] {-1, 0, 1, 0};
private static int[] dc = new int[] {0, 1, 0, -1};
private static void visitNearby(int r, int c) {
visited[r][c] = true;
if (map[r][c] == WOLF) {
currentSectionWolvesCnt++;
}
else if (map[r][c] == SHEEP) {
currentSectionSheepCnt++;
}
for (int dir = 0; dir < 4; dir++) {
int nextR = r + dr[dir];
int nextC = c + dc[dir];
if (nextR < 0 || nextR == R || nextC < 0 || nextC == C) {
continue;
}
if (map[nextR][nextC] != WALL && !visited[nextR][nextC]) {
visitNearby(nextR, nextC);
}
}
}
}