'#'은 울타리를 의미한다.
양과 늑대는 울타리를 넘어갈 수는 없지만, 그 외 모든 구역은 갈 수 있다.
한 울타리 내에서 양 > 늑대라면 늑대가 사라지고, 늑대 > 양이라면 양이 사라진다.
이 때 마지막에 살아남은 양과 늑대의 수를 출력하는 문제이다.
'#'으로 둘러 쌓인 부분에 존재하는 양의 개수와 늑대의 개수를 세면 되는 문제이다.
#을 1로 설정하고, 1이 아닌 점을 만나면 그래프 탐색을 수행하면 된다.
문제는, 그래프 탐색을 수행할 때 v를 만나면 늑대의 수를 1증가시키고, o를 만나면 양의 수를 1증가시켜 마지막에 최종 양과 늑대 수를 비교해야 한다.
이런 로직을 재귀함수로 구현하기엔 어려운 점이 있을 것 같아 Queue를 통해 한 개의 메서드 내에서 모두 처리할 수 있는 BFS를 활용하기로 하였다.
또한, '.','o','v'를 만나면 해당 공간을 1 값으로 바꾸어 이미 방문했다는 표기를 해야 한다. 1로 표기한 이유는 1은 울타리를 의미했기 때문에 접근 할 수 없다는 점에서 같은 의미를 가지므로 위와 같은 방법을 사용했다.
마지막으로 한 번의 BFS를 수행할 때 마다 양 혹은 늑대 중 수가 많은 것만 살아 남을 것이다. 따라서, BFS 수행 마지막 부분에 양과 늑대의 수 비교 및 전체 양, 늑대 수에 해당 비교 결과를 첨부해 줘야 할 것이다.
import java.io.*;
import java.util.*;
class Point{
int x;
int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
}
public class Main {
static int N,M;
static int[][] arr;
static int ans_wolf = 0; // 최종 늑대 수
static int ans_sheep = 0; // 최종 양 수
// 0 : 빈 공간, 1 : 울타리, 2 : 양, 3 : 늑대
static void bfs(int i, int j) {
Point start = new Point(i,j);
Queue<Point> points = new LinkedList<>();
points.add(start);
int wolf = 0;
int sheep = 0;
while(!points.isEmpty()) {
// 최단 거리를 구하는 것이 아니므로 그래프의 모든 점을
// Search할 때 까지 반복문을 돌려야 함
Point tmp = points.poll();
if(tmp.x<0||tmp.x>=N||tmp.y<0||tmp.y>=M) continue;
if(arr[tmp.x][tmp.y]==1) {
// 이미 방문했던 점이거나, 울타리이므로 생략
continue;
}
if(arr[tmp.x][tmp.y]==2) {
sheep++;
}
else if(arr[tmp.x][tmp.y]==3) {
wolf++;
}
arr[tmp.x][tmp.y] = 1; // 방문했다고 표기하는 처리
points.add(new Point(tmp.x-1,tmp.y));
points.add(new Point(tmp.x+1,tmp.y));
points.add(new Point(tmp.x,tmp.y-1));
points.add(new Point(tmp.x,tmp.y+1));
}
if(sheep > wolf) {
// 양이 많은 상황. 전체 양의 수의 이번 DFS의 양 결과를 더해줌
ans_sheep+=sheep;
}
else {
// 늑대가 양보다 많거나 같은 경우
// 늑대가 양을 잡아먹으므로 전체 늑대의 수에 추가시켜줌
ans_wolf+=wolf;
}
}
public static void main(String[] args) {
FastReader sc = new FastReader();
StringBuilder sb = new StringBuilder();
N = sc.nextInt();
M = sc.nextInt();
arr = new int[N][M];
for(int i =0;i<N;i++) {
String tmp = sc.next();
for(int j =0;j<M;j++) {
char c = tmp.charAt(j);
switch(c) {
case '#':
arr[i][j] = 1;
break;
case 'o':
arr[i][j] = 2;
break;
case 'v':
arr[i][j] = 3;
break;
}
}
}
for(int i =0;i<N;i++) {
for(int j =0;j<M;j++) {
if(arr[i][j]!=1) {
// 새로운 그래프(방문하지 않았던 그래프)이므로 BFS 수행
bfs(i, j);
}
}
}
System.out.println(ans_sheep+" "+ans_wolf);
}
static class FastReader // 빠른 입력을 위한 클래스
}