[Java] 백준 10026번 적록색약

2023. 3. 3. 16:56나는 이렇게 학습한다/Algorithm

이 글은 백준 10026번 적록색약을 풀이한다. 코드는 Java로 구현하였다.

문제

적록색약은 빨간색과 초록색의 차이를 거의 느끼지 못한다. 따라서, 적록색약인 사람이 보는 그림은 아닌 사람이 보는 그림과는 좀 다를 수 있다.

크기가 N×N인 그리드의 각 칸에 R(빨강), G(초록), B(파랑) 중 하나를 색칠한 그림이 있다. 그림은 몇 개의 구역으로 나뉘어져 있는데, 구역은 같은 색으로 이루어져 있다. 또, 같은 색상이 상하좌우로 인접해 있는 경우에 두 글자는 같은 구역에 속한다. (색상의 차이를 거의 느끼지 못하는 경우도 같은 색상이라 한다)

예를 들어, 그림이 아래와 같은 경우에

RRRBB
GGBBB
BBBRR
BBRRR
RRRRR

적록색약이 아닌 사람이 봤을 때 구역의 수는 총 4개이다. (빨강 2, 파랑 1, 초록 1) 하지만, 적록색약인 사람은 구역을 3개 볼 수 있다. (빨강-초록 2, 파랑 1)

그림이 입력으로 주어졌을 때, 적록색약인 사람이 봤을 때와 아닌 사람이 봤을 때 구역의 수를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 N이 주어진다. (1 ≤ N ≤ 100)

둘째 줄부터 N개 줄에는 그림이 주어진다.

예제 입력 1

5
RRRBB
GGBBB
BBBRR
BBRRR
RRRRR

출력

적록색약이 아닌 사람이 봤을 때의 구역의 개수와 적록색약인 사람이 봤을 때의 구역의 수를 공백으로 구분해 출력한다.

예제 출력 1

4 3

제한

  • 시간: 1초
  • 메모리: 128MB

풀이

접근

기초적인 bfs 문제였다.

이중 for문을 사용해서 bfs 시작점을 찾을 때마다 구역 count 개수를 늘린다.

 

입력받는 배열로 적록색약이 아닌 사람의 bfs를 한번 구하고,

적록색약인 사람은 빨간색과 초록색의 차이를 구분하지 못하기에, 초록색을 빨간색으로 통일시킨 뒤에 bfs를 구한다.

 

그리고 마지막에 개수를 각각 출력해준다.

구현

코드

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.Queue;

class Pair {

  int X, Y;

  Pair(int X, int Y) {
    this.X = X;
    this.Y = Y;
  }
}

public class Main {

  static char[][] board;
  static boolean[][] visit;
  static Queue<Pair> Q;
  static int N;
  static int[] dx = { 1, 0, -1, 0 };
  static int[] dy = { 0, 1, 0, -1 };

  static void bfs(int x, int y) {
    visit[x][y] = true;
    Q.offer(new Pair(x, y));
    while (!Q.isEmpty()) {
      Pair cur = Q.poll();
      for (int dir = 0; dir < 4; dir++) {
        int nx = cur.X + dx[dir];
        int ny = cur.Y + dy[dir];
        if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;
        if (visit[nx][ny] || board[nx][ny] != board[x][y]) continue;
        visit[nx][ny] = true;
        Q.offer(new Pair(nx, ny));
      }
    }
  }

  static int area() {
    int count = 0;
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < N; j++) {
        if (visit[i][j]) continue;
        bfs(i, j);
        count++;
      }
    }
    return count;
  }

  public static void main(String[] args) throws IOException {
    BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    N = Integer.parseInt(br.readLine());
    board = new char[N][N];
    visit = new boolean[N][N];
    Q = new LinkedList<>();
    // 배열 입력
    for (int i = 0; i < N; i++) {
      String s = br.readLine();
      for (int j = 0; j < N; j++) {
        board[i][j] = s.charAt(j);
      }
    }
    int no_count = area(); // 정상인 카운트

    // visit 배열 false로 초기화
    for (boolean vis[] : visit) {
      Arrays.fill(vis, false);
    }
    // 적록색약이 있는 사람은 빨강과 초록을 구분하지 못하므로, 초록색을 빨강으로 변경
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < N; j++) {
        if (board[i][j] == 'G') {
          board[i][j] = 'R';
        }
      }
    }

    int yes_count = area(); // 색맹인 카운트

    System.out.printf("%d %d", no_count, yes_count);
  }
}

 

반응형

'나는 이렇게 학습한다 > Algorithm' 카테고리의 다른 글

[Java] 백준 1697번 숨바꼭질  (0) 2023.02.27
[Java] 백준 4179번 불!  (0) 2023.02.24
[Java] 백준 7576번 토마토  (0) 2023.02.23
[Java] 백준 2178번 미로 탐색  (0) 2023.02.22
[Java] 백준 1926번 그림  (0) 2023.02.22