10026번 적녹색약
10026번 적녹색약
https://www.acmicpc.net/problem/10026
풀이
이 문제는 적록색약인 사람과 그렇지 않은 사람이 보는 그림에서 각각의 구역의 수를 세는 문제입니다. BFS (Breadth-First Search)를 사용하여 연결된 구성 요소의 수를 계산하는 방식으로 해결할 수 있습니다.
- 두 가지 보드 준비:
- 일반적인 경우를 위한
board: ‘R’, ‘G’, ‘B’를 각각 다른 숫자로 매핑합니다. (예: R=1, G=2, B=3) - 적록색약인 경우를 위한
board_week: ‘R’과 ‘G’를 같은 숫자로 매핑하고 ‘B’는 다른 숫자로 매핑합니다. (예: R=1, G=1, B=3)
- 일반적인 경우를 위한
- BFS 함수 구현:
BFS(board, visited, x, y)함수는 주어진(x, y)좌표에서 시작하여 동일한 색상을 가진 모든 인접한 셀을 탐색합니다.visited배열을 사용하여 이미 방문한 셀을 추적하여 중복 계산을 방지합니다.- 큐를 사용하여 BFS 탐색을 수행하고, 현재 셀의 색상과 동일한 인접 셀을 큐에 추가하고 방문 처리합니다.
- 구역 수 계산:
- 두 개의 별도의
visited배열(visited및visited_week)을 사용하여 일반적인 경우와 적록색약인 경우를 각각 추적합니다. - 두 개의 카운터(
cnt및cnt_week)를 0으로 초기화합니다. - 전체 보드를 순회하면서:
- 만약 현재 셀이 일반
visited배열에서 방문되지 않았다면,BFS(board, visited, i, j)를 호출하고cnt를 1 증가시킵니다. - 만약 현재 셀이 적록색약
visited_week배열에서 방문되지 않았다면,BFS(board_week, visited_week, i, j)를 호출하고cnt_week를 1 증가시킵니다.
- 만약 현재 셀이 일반
- 두 개의 별도의
- 결과 출력:
- 최종적으로
cnt와cnt_week를 출력합니다.
- 최종적으로
이 방법은 두 가지 다른 관점에서 그림의 연결된 구성 요소를 효율적으로 계산하여 문제를 해결합니다.
시간 복잡도: 이 문제는 $N \times N$ 크기의 그리드에서 BFS를 두 번 수행합니다. BFS는 모든 정점과 간선을 한 번씩 방문하므로, 시간 복잡도는 $O(V + E)$입니다. 여기서 $V$는 그리드의 칸 수 ($N^2$), $E$는 간선의 수 (각 칸마다 최대 4개의 인접한 칸으로 연결될 수 있으므로 대략 $4N^2$)입니다. 따라서, 두 번의 BFS를 포함한 전체 시간 복잡도는 $O(N^2)$입니다.
공간 복잡도: 큐에 최악의 경우 $O(N^2)$개의 칸이 저장될 수 있으며, visited 배열 또한 $O(N^2)$의 공간을 사용합니다. 따라서, 공간 복잡도는 $O(N^2)$입니다.
코드
10026.cpp
#include <bits/stdc++.h>
using namespace std;
constexpr array<int, 4> dx = {1, 0, -1, 0};
constexpr array<int, 4> dy = {0, 1, 0, -1};
void BFS(const vector<vector<int>>& board, vector<vector<bool>>& visited, int x, int y){
queue<pair<int, int>> q;
q.push({x, y});
visited[x][y] = true;
const int currColor = board[x][y];
while(!q.empty()){
auto [x, y] = q.front();
q.pop();
for(int i = 0;i<4;i++){
int nx = x + dx[i];
int ny = y + dy[i];
if(nx < 0 || nx >= board.size() || ny < 0 || ny >= board[0].size() || visited[nx][ny] || board[nx][ny] != currColor){
continue;
}
visited[nx][ny] = true;
q.push({nx, ny});
}
}
}
int main(){
ios_base::sync_with_stdio(false);
cin.tie(nullptr);
int N;
cin >> N;
auto board = vector(N, vector(N, 0)); // 0: Unknown, 1: Red, 2: Green, 3: Blue
auto board_week = vector(N, vector(N, 0));
string s;
for(int i = 0;i<N;i++){
cin >> s;
for(int j = 0;j<N;j++){
if(s[j] == 'R'){
board[i][j] = 1;
board_week[i][j] = 1;
}
else if(s[j] == 'G'){
board[i][j] = 2;
board_week[i][j] = 1;
}
else if(s[j] == 'B'){
board[i][j] = 3;
board_week[i][j] = 3;
}
}
}
int cnt = 0, cnt_week = 0;
auto visited = vector(N, vector(N, false));
auto visited_week = vector(N, vector(N, false));
for(int i = 0;i<N;i++){
for(int j = 0;j<N;j++){
if(!visited[i][j]){
BFS(board, visited, i, j);
cnt++;
}
if(!visited_week[i][j]){
BFS(board_week, visited_week, i, j);
cnt_week++;
}
}
}
cout << cnt << " " << cnt_week << '\n';
return 0;
} C++
This post is licensed under CC BY 4.0 by the author.