본문 바로가기

코딩테스트/c++

[백준] 10026번 적록색약

728x90

 

전형적인 BFS 문제로 두 번째 경우에서 빨간색과 초록색을 동일한 색깔로 보는 조건만 처리해주면 된다.

 

 

각 칸에 색깔을 넣어준 뒤 변수들을 선언한다.

 

 

2중 for문을 돌며 방문하지 않은 곳이면 q에 넣고 BFS를 시작한다. curColor에는 시작한 구역의 색깔을 저장한 후 그 색깔에 맞는 count를 더해준다.

 

 

현재 위치의 상,하,좌,우를 확인하며 curColor와 같은 색깔일 경우 큐에 삽입 후 방문 표시를 한다.

 

 

 

2중 for문이 끝나면 각 색깔의 count를 더하여 출력한다.

 

 

rgCount는 빨간색과 초록색의 구역의 개수를 합친 것이다. visited의 모든 값들을 false로 초기화한다.

 

 

BFS 시작하는건 앞에서 했던 코드와 동일하고 상,하,좌,우 확인하면서 큐에 삽입할 때 현재 빨간색과 초록색을 동일한 색깔로 보기 때문에 조건문을 넣어야 한다.

 

 

전체 코드

#include <bits/stdc++.h>

using namespace std;

int dx[4] = { -1,0,1,0 };
int dy[4] = { 0,-1,0,1 };

vector<vector<char>> board(101, vector<char>(101));
int N;

int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	cin >> N;

	for (int i = 0; i < N; i++) {
		string str;
		cin >> str;

		for (int j = 0; j < str.length(); j++) 
			board[i][j] = str[j];
	}

	int rCount = 0; // 빨간색 구역의 수
	int gCount = 0; // 초록색 구역의 수
	int bCount = 0; // 파란색 구역의 수

	vector<vector<bool>> visited(101, vector<bool>(101, false)); // 방문 표시
	

	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			if (visited[i][j])
				continue;

			queue<pair<int, int>> q;

			q.push({ i,j });
			visited[i][j] = true;
			char curColor = board[i][j]; // 현재 위치의 색깔

			if (curColor == 'R')
				rCount++;
			else if (curColor == 'G')
				gCount++;
			else
				bCount++;

			// 현재 위치와 연결된 칸들을 방문 표시한다.
			while (!q.empty()) {
				auto cur = q.front();
				q.pop();

				for (int k = 0; k < 4; k++) {
					int xpos = cur.first + dx[k];
					int ypos = cur.second + dy[k];

					if (xpos < 0 or xpos >= N or ypos < 0 or ypos >= N)
						continue;
					if (visited[xpos][ypos] or curColor != board[xpos][ypos])
						continue;
					q.push({ xpos,ypos });
					visited[xpos][ypos] = true;
				}
			}
		}
	}

	// 모든 구역의 수를 더하여 출력
	cout << rCount + gCount + bCount << " ";

	int rgCount = 0; // 빨간색과 초록색 구역을 합친 수
	bCount = 0; // 파란색 구역의 수

	// 방문 표시 초기화
	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			visited[i][j] = false;
		}
	}

	for (int i = 0; i < N; i++) {
		for (int j = 0; j < N; j++) {
			if (visited[i][j])
				continue;

			queue<pair<int, int>> q;

			q.push({ i,j });
			visited[i][j] = true;
			char curColor = board[i][j];

			if (curColor == 'R' or curColor == 'G') // 방문한 곳이 빨강 또는 초록일 경우
				rgCount++;
			else
				bCount++;

			while (!q.empty()) {
				auto cur = q.front();
				q.pop();

				for (int k = 0; k < 4; k++) {
					int xpos = cur.first + dx[k];
					int ypos = cur.second + dy[k];

					if (xpos < 0 or xpos >= N or ypos < 0 or ypos >= N)
						continue;
					if (visited[xpos][ypos])
						continue;
					if (curColor == 'R' or curColor == 'G') { // 현재 체크하고 있는 구역의 색깔이 빨강 또는 초록일 경우
						if (board[xpos][ypos] == 'B') // 빨강 또는 초록을 체크하고 있으므로 파랑일 경우는 pass
							continue;
					}
					else { // 현재 체크하고 있는 구역의 색깔이 파랑일 경우
						if (board[xpos][ypos] != 'B') // 파랑을 체크하고 있으므로 다른 경우는 pass
							continue;
					}
					q.push({ xpos,ypos });
					visited[xpos][ypos] = true;
				}
			}
		}
	}

	cout << rgCount + bCount;

	return 0;
}
728x90
반응형