Algorithm/문제풀이

[BFS] 적록색약

lee308812 2019. 10. 29. 04:28

예제 입력 1

5

RRRBB

GGBBB

BBBRR

BBRRR

RRRRR

예제 출력 1

4 3

 

https://www.acmicpc.net/problem/10026

 

10026번: 적록색약

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

www.acmicpc.net

- 동일한 색깔끼리 BFS를 이용하여 그룹으로 묶는다.

- 일반인의 경우와 적록색약의 경우(빨강색과 초록색을 동일하게 처리) 2번 BFS 돌림.

#include <stdio.h>

constexpr int MAX_QUEUE_SIZE = 20000;
constexpr int MAX_COUNT = 101;

int N;

char map[MAX_COUNT][MAX_COUNT];
short group[MAX_COUNT][MAX_COUNT];
short groupForBlind[MAX_COUNT][MAX_COUNT];

int dR[] = { -1, 1, 0, 0 };
int dC[] = { 0, 0, -1, 1 };

class Point
{
public:
	int r;
	int c;

	Point() { r = c = 0; }
	Point(int r, int c) : r(r), c(c) {}
	
	bool IsInBoundary(int N)
	{
		return (r >= 0) && (r < N) && (c >= 0) && (c < N);
	}
};

template <typename T>
class Queue
{
private:
	int front;
	int rear;
	T items[MAX_QUEUE_SIZE];

public:
	Queue() { front = rear = 0; }

	void push(T item)
	{
		items[rear] = item;
		rear = (rear + 1) % MAX_QUEUE_SIZE;
	}

	T pop()
	{
		T result = items[front];
		front = (front + 1) % MAX_QUEUE_SIZE;

		return result;
	}

	bool isEmpty() { return front == rear; }
};
Queue<Point> q;

int BFS(short (*groupMap)[MAX_COUNT], bool RGSame = false)
{
	int result = 0;

	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < N; j++)
		{
			if (groupMap[i][j] == -1)
			{
				Point init(i, j);
				groupMap[i][j] = result;
				q.push(init);

				while (!q.isEmpty())
				{
					Point now = q.pop();

					for (int k = 0; k < 4; k++)
					{
						Point next(now.r + dR[k], now.c + dC[k]);
						
						if (!next.IsInBoundary(N)) continue;

						if (groupMap[next.r][next.c] == -1)
						{
							if ((map[next.r][next.c] == map[init.r][init.c]) || 
								(RGSame && ((map[init.r][init.c] == 'R' && map[next.r][next.c] == 'G') || 
									(map[init.r][init.c] == 'G' && map[next.r][next.c] == 'R'))))
							{
								groupMap[next.r][next.c] = result;
								q.push(next);
							}
						}
					}
				}

				result++;
			}
		}
	}

	return result;
}

int main(void)
{
	scanf("%d", &N);

	for (int i = 0; i < N; i++)
	{
		for (int j = 0; j < N; j++)
		{
			while (true)
			{
				scanf("%c", &map[i][j]);

				if (map[i][j] != '\n') break;
			}

			group[i][j] = -1;
			groupForBlind[i][j] = -1;
		}
	}

	printf("%d\n", BFS(group));
	printf("%d\n", BFS(groupForBlind, true));
	
	return 0;
}

 

'Algorithm > 문제풀이' 카테고리의 다른 글

[그리디 알고리즘] 동전 0  (0) 2019.10.30
[BFS] 4연산  (0) 2019.10.30
[BFS] 레이저 통신  (0) 2019.10.29
[BFS] 아기 상어  (0) 2019.10.24
[BFS] 탈출  (0) 2019.10.24