문제 설명
주어진 N×N 크기의 그리드에서, 각 칸은 빨간색(R), 초록색(G), 파란색(B) 중 하나로 색칠되어 있다.
이 그리드에서 같은 색상의 칸들이 상하좌우로 인접하면 같은 구역을 이루게 된다.
문제는 적록색약인 사람과 그렇지 않은 사람이 봤을 때 구역의 수를 계산하는 것이다.
적록색약인 사람은 빨간색과 초록색의 차이를 거의 느끼지 못하므로 빨간색과 초록색을 같은 색상으로 본다.
적록색약이 아닌 사람은 각 색상을 구분하여 구역을 나눈다. 따라서 문제는 두 가지 경우의 구역 수를 계산해야 한다.
1. 적록색약이 아닌 사람의 구역 수 계산
: 일반적으로 각 칸에 대해 상하좌우로 연결된 같은 색을 하나의 구역으로 본다.
-> 이를 구하기 위해 BFS 또는 DFS 알고리즘을 활용하여 연결된 칸들을 탐색하고, 구역의 수를 센다.
2. 적록색약인 사람의 구역 수 계산
: 적록색약인 사람은 빨간색과 초록색을 구분하지 않으므로, 빨간색과 초록색을 동일한 색으로 취급한다.
-> 빨간색과 초록색을 같은 색으로 변경한 후, 다시 BFS 또는 DFS를 활용하여 구역을 센다.
import java.util.Scanner;
public class Main {
static int N;
static char[][] grid;
static boolean[][] visited;
// 4방향으로 상하좌우 탐색
static int[] dx = {-1, 1, 0, 0};
static int[] dy = {0, 0, -1, 1};
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
N = sc.nextInt();
grid = new char[N][N];
visited = new boolean[N][N];
// 그리드 입력 받기
sc.nextLine(); // 개행 문자 처리
for (int i = 0; i < N; i++) {
grid[i] = sc.nextLine().toCharArray();
}
// 적록색약이 아닌 사람의 구역 수 구하기
int normalRegions = countRegions(false);
// 적록색약인 사람의 구역 수 구하기
int colorBlindRegions = countRegions(true);
System.out.println(normalRegions + " " + colorBlindRegions);
sc.close();
}
// 구역을 세는 함수
public static int countRegions(boolean isColorBlind) {
visited = new boolean[N][N]; // 방문 기록 초기화
int regionCount = 0;
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (!visited[i][j]) {
regionCount++;
dfs(i, j, grid[i][j], isColorBlind); // DFS 호출
}
}
}
return regionCount;
}
// DFS 탐색 함수
public static void dfs(int x, int y, char color, boolean isColorBlind) {
visited[x][y] = true;
for (int i = 0; i < 4; i++) {
int nx = x + dx[i];
int ny = y + dy[i];
if (nx >= 0 && ny >= 0 && nx < N && ny < N && !visited[nx][ny]) {
// 적록색약인 경우, 빨강과 초록을 동일하게 취급
if (isColorBlind) {
if ((color == 'R' || color == 'G') && (grid[nx][ny] == 'R' || grid[nx][ny] == 'G')) {
dfs(nx, ny, color, isColorBlind);
} else if (color == grid[nx][ny]) {
dfs(nx, ny, color, isColorBlind);
}
} else {
// 적록색약이 아닌 경우, 색상이 같으면 이어진 구역으로 탐색
if (color == grid[nx][ny]) {
dfs(nx, ny, color, isColorBlind);
}
}
}
}
}
}
풀이 설명
- 입력 받기 : 첫째 줄에서 N을 입력받고, N×N 그리드에서 각 칸의 색을 입력받았다.
- 구역 세기 : countRegions 함수는 DFS(깊이 우선 탐색)를 사용하여 구역을 세는 함수이다.
isColorBlind가 true일 경우, 빨간색과 초록색을 같은 색으로 취급하여 구역을 세고, 그렇지 않으면 색상에 맞춰 구역을 센다.
- DFS 탐색 : dfs 함수는 주어진 칸을 시작으로 상하좌우를 탐색하며 연결된 같은 색의 칸들을 방문 처리하고, 하나의 구역을 완성한다.
적록색약인 경우 빨간색과 초록색을 동일시하여 탐색한다.
- 결과 출력 : 적록색약이 아닌 사람과 적록색약인 사람이 봤을 때의 구역 수를 각각 계산하여 출력한다.
정리
적록색약이 아닌 사람은 각 색상을 구분하여 구역을 세고, 적록색약인 사람은 빨간색과 초록색을 구분하지 않으므로 두 가지 경우의 구역 수를 계산하여 출력했다.
이 문제는 DFS 또는 BFS를 이용한 전형적인 탐색 문제로, 색상을 구분할 때 조건을 어떻게 처리하느냐에 따라 풀이가 달라진다.
댓글
댓글 작성은 로그인 후에 가능합니다.