10026번
문제
- 적록색약은 빨간색과 초록색의 차이를 거의 느끼지 못한다. 따라서, 적록색약인 사람이 보는 그림은 아닌 사람이 보는 그림과는 좀 다를 수 있다.
크기가 N×N인 그리드의 각 칸에 R(빨강), G(초록), B(파랑) 중 하나를 색칠한 그림이 있다. 그림은 몇 개의 구역으로 나뉘어져 있는데, 구역은 같은 색으로 이루어져 있다. 또, 같은 색상이 상하좌우로 인접해 있는 경우에 두 글자는 같은 구역에 속한다. (색상의 차이를 거의 느끼지 못하는 경우도 같은 색상이라 한다)
예를 들어, 그림이 아래와 같은 경우에
RRRBB
GGBBB
BBBRR
BBRRR
RRRRR
적록색약이 아닌 사람이 봤을 때 구역의 수는 총 4개이다. (빨강 2, 파랑 1, 초록 1) 하지만, 적록색약인 사람은 구역을 3개 볼 수 있다. (빨강-초록 2, 파랑 1)
그림이 입력으로 주어졌을 때, 적록색약인 사람이 봤을 때와 아닌 사람이 봤을 때 구역의 수를 구하는 프로그램을 작성하시오.
문제 해결 순서
- 구역을 저장할 배열 arr과 방문을 체크할 배열 visit을 선언한다
- 탐색은 dfs알고리즘을 사용했으며, 한번 탐색하면서 자신이 G인 경우 R로 바꿔줬다. (색맹을 위해)
- 첫 dfs 탐색을 하며 저장한 구역을 합쳐서 출력한 후 visit배열과 구역 변수를 초기화한다.
- 두번째로 G 구역이 R 구역으로 바뀐 배열을 dfs 탐색하며 저장한 구역을 합쳐서 출력한다.
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Scanner;
public class Main {
static boolean visit[][];
static String arr[][];
static int length;
static int areaR;
static int areaB;
static int areaG;
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
length = scan.nextInt();
visit = new boolean[length][length];
arr = new String[length][length];
scan.nextLine();
for (int i = 0; i < length; i++) {
String temp = scan.nextLine();
arr[i] = temp.split("");
}
for (int i = 0; i < length; i++) {
for (int j = 0; j < length; j++) {
if (!visit[i][j]) {
dfs(i, j);
if (arr[i][j].equals("R"))
areaR++;
if (arr[i][j].equals("G"))
areaG++;
if (arr[i][j].equals("B"))
areaB++;
}
}
}
// 정상 출력
System.out.println(areaR + areaG + areaB);
// 방문 초기화
resetVisit(visit);
// 색맹 출력
for (int i = 0; i < length; i++) {
for (int j = 0; j < length; j++) {
if (!visit[i][j]) {
dfs(i, j);
if (arr[i][j].equals("R"))
areaR++;
if (arr[i][j].equals("B"))
areaB++;
}
}
}
System.out.println(areaR + areaB);
}
static void resetVisit(boolean visit[][]){
areaB = 0;
areaG = 0;
areaR = 0;
for (int i = 0; i < length; i++) {
for (int j = 0; j < length; j++) {
visit[i][j] = false;
}
}
}
static void dfs(int x, int y) {
String color;
color = arr[x][y];
visit[x][y] = true;
// 상, 색깔이 같고, 위로 갈 수 있고, 방문하지 않았으면
if (x - 1 >= 0 && color.equals(arr[x - 1][y]) && !visit[x - 1][y]) {
dfs(x - 1, y);
}
// 하, 색깔이 같고, 밑으로 갈 수 있고, 방문하지 않았으면
if (x + 1 < length && color.equals(arr[x + 1][y]) && !visit[x + 1][y]) {
dfs(x + 1, y);
}
// 좌, 색깔이 같고, 왼쪽으로 갈 수 있고, 방문하지 않았으면
if (y - 1 >= 0 && color.equals(arr[x][y - 1]) && !visit[x][y - 1]) {
dfs(x, y - 1);
}
// 우, 색깔이 같고, 왼쪽으로 갈 수 있고, 방문하지 않았으면
if (y + 1 < length && color.equals(arr[x][y + 1]) && !visit[x][y + 1]) {
dfs(x, y + 1);
}
if (color.equals("G"))
arr[x][y] = "R";
}
}

