🔗 문제 링크 : https://www.acmicpc.net/problem/10026
문제
적록색약은 빨간색과 초록색의 차이를 거의 느끼지 못한다. 따라서, 적록색약인 사람이 보는 그림은 아닌 사람이 보는 그림과는 좀 다를 수 있다.
크기가 N×N인 그리드의 각 칸에 R(빨강), G(초록), B(파랑) 중 하나를 색칠한 그림이 있다. 그림은 몇 개의 구역으로 나뉘어져 있는데, 구역은 같은 색으로 이루어져 있다. 또, 같은 색상이 상하좌우로 인접해 있는 경우에 두 글자는 같은 구역에 속한다. (색상의 차이를 거의 느끼지 못하는 경우도 같은 색상이라 한다)
예를 들어, 그림이 아래와 같은 경우에
RRRBB
GGBBB
BBBRR
BBRRR
RRRRR
적록색약이 아닌 사람이 봤을 때 구역의 수는 총 4개이다. (빨강 2, 파랑 1, 초록 1) 하지만, 적록색약인 사람은 구역을 3개 볼 수 있다. (빨강-초록 2, 파랑 1)
그림이 입력으로 주어졌을 때, 적록색약인 사람이 봤을 때와 아닌 사람이 봤을 때 구역의 수를 구하는 프로그램을 작성하시오.
입출력 예시
입력
첫째 줄에 N이 주어진다. (1 ≤ N ≤ 100)
둘째 줄부터 N개 줄에는 그림이 주어진다.
출력
적록색약이 아닌 사람이 봤을 때의 구역의 개수와 적록색약인 사람이 봤을 때의 구역의 수를 공백으로 구분해 출력한다.
풀이
BFS는 총 두 번 실행하며, 접근은 아래와 같다.
- 그림을 입력 받을 때, 적록색약이 아닌 사람이 보는 그림을 image0 배열에 담고, 적록색약인 사람이 보는 그림을 image1에 담는다.
- image1에 색상 정보가 담기는 과정 : 입력값이 초록(G) 색상의 경우, image1 배열에는 빨강(R)으로 바꾸어서 저장한다.
- 따라서, image0에는 R, G, B 3가지 색상이 저장되고, image1에는 R, B 총 2가지 색상이 저장된다.
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
cin >> image0[i][j];
if (image0[i][j] == 'G')
image1[i][j] = 'R';
else
image1[i][j] = image0[i][j];
}
}
- 이후 image0과 image1 배열에 대한 BFS를 실행하여 구역의 수를 각각 구한다.
#include <iostream>
#include <vector>
#include <queue>
using namespace std;
int dirX[4] = {-1, 1, 0, 0};
int dirY[4] = {0, 0, -1, 1};
struct Pos {
Pos (int x, int y) {
this->x = x;
this->y = y;
}
int x;
int y;
};
int main() {
ios_base::sync_with_stdio(0);
int result0 = 0;
int result1 = 0;
int N;
cin >> N;
vector<vector<char>> image0(N, vector<char>(N));
vector<vector<char>> image1(N, vector<char>(N));
vector<vector<int>> visited(N, vector<int>(N, 0));
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
cin >> image0[i][j];
if (image0[i][j] == 'G')
image1[i][j] = 'R';
else
image1[i][j] = image0[i][j];
}
}
/* 적록색약 x */
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (visited[i][j] == 1) continue;
queue<Pos> q;
q.push(Pos(i, j));
visited[i][j] = 1;
result0++;
while(!q.empty()) {
Pos curr = q.front();
q.pop();
for (int dir = 0; dir < 4; dir++) {
int nx = curr.x + dirX[dir];
int ny = curr.y + dirY[dir];
if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;
if (visited[nx][ny] != 0 || image0[nx][ny] != image0[i][j]) continue;
q.push(Pos(nx, ny));
visited[nx][ny] = 1;
}
}
}
}
for (int i = 0; i < N; i++) {
fill(visited[i].begin(), visited[i].end(), 0);
}
/* 적록색약 o */
for (int i = 0; i < N; i++) {
for (int j = 0; j < N; j++) {
if (visited[i][j] == 1) continue;
queue<Pos> q;
q.push(Pos(i, j));
visited[i][j] = 1;
result1++;
while(!q.empty()) {
Pos curr = q.front();
q.pop();
for (int dir = 0; dir < 4; dir++) {
int nx = curr.x + dirX[dir];
int ny = curr.y + dirY[dir];
if (nx < 0 || nx >= N || ny < 0 || ny >= N) continue;
if (visited[nx][ny] != 0 || image1[i][j] != image1[nx][ny]) continue;
q.push(Pos(nx, ny));
visited[nx][ny] = 1;
}
}
}
}
cout << result0 << ' ' << result1;
}
'🐸 Problem Solving > BOJ' 카테고리의 다른 글
[BOJ/C++] 백준 15649번: N과 M (1) (0) | 2024.09.11 |
---|---|
[BOJ/C++] 백준 7576번: 토마토 (0) | 2024.09.09 |
[BOJ/C++] 백준 2003번: 수들의 합 (0) | 2024.09.06 |