Algorithm/문제풀이

[BFS] 레이저 통신

lee308812 2019. 10. 29. 03:21

예제 입력 1

7 8

.......

......C

......*

*****.

....*..

....*..

.C..*..

.......

예제 출력 1

3

 

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

 

6087번: 레이저 통신

문제 크기가 1×1인 정사각형으로 나누어진 W×H 크기의 지도가 있다. 지도의 각 칸은 빈 칸이거나 벽이며, 두 칸은 'C'로 표시되어 있는 칸이다. 'C'로 표시되어 있는 두 칸을 레이저로 통신하기 위해서 설치해야 하는 거울 개수의 최솟값을 구하는 프로그램을 작성하시오. 레이저로 통신한다는 것은 두 칸을 레이저로 연결할 수 있음을 의미한다. 레이저는 C에서만 발사할 수 있고, 빈 칸에 거울('/', '\')을 설치해서 방향을 90도 회전시킬 수 있다. 

www.acmicpc.net

- 거리가 중요한 것이 아니고 방향을 바꾸는 횟수를 최소화 하는 것이 목적이므로, 상하좌우로 더이상 이동할 수 없을 때까지 모두 동일한 거리로 대입하고 큐에 넣는다. 큐에서 꺼내고 다시 상하좌우로 이동할 때 방향이 바뀌는 것이므로 거리를 + 1하여 저장하는 식으로 처리한다.

 

- 답은 -1을 해줘야한다. 선분의 개수가 아닌 꺾이는 횟수이기 때문.

#include <stdio.h>
#define MIN(a,b) ((a)<(b)?(a):(b))

constexpr int MAX_SIZE = 101;
constexpr int MAX_QUEUE_SIZE = 20000;

int R, C;
char map[MAX_SIZE][MAX_SIZE];
int dist[MAX_SIZE][MAX_SIZE];

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

int result = 10000000;

class Point
{
public:
	int r;
	int c;

	Point() { r = c = 0; }
	Point(int r, int c) : r(r), c(c) {}

	bool IsInBoundary(int R, int C)
	{
		return (r >= 0 && r < R && c >= 0 && c < C);
	}

	bool operator==(Point other)
	{
		return (r == other.r) && (c == other.c);
	}
};
Point equipment[2];

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

public:
	Queue() { rear = front; }

	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()
{
	dist[equipment[0].r][equipment[0].c] = 0;
	q.push(equipment[0]);

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

		if (now == equipment[1])
		{
			result = MIN(result, dist[now.r][now.c]);
		}

		for (int i = 0; i < 4; i++)
		{
			int moveCnt = 1;

			while (true)
			{
				Point next(now.r + (dR[i] * moveCnt),
					now.c + (dC[i] * moveCnt));

				if (!next.IsInBoundary(R, C)) break;
				if (map[next.r][next.c] == '*') break;
				if (dist[next.r][next.c] == -1)
				{
					dist[next.r][next.c] = dist[now.r][now.c] + 1;
					q.push(next);
				}

				moveCnt++;
			}
		}
	}

	return result-1;
}

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

	int equipmentIdx = 0;

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

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

			dist[i][j] = -1;

			if (map[i][j] == 'C')
			{
				equipment[equipmentIdx].r = i;
				equipment[equipmentIdx].c = j;
				equipmentIdx++;
			}
		}
	}

	printf("%d\n", BFS());

	return 0;
}

 

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

[BFS] 4연산  (0) 2019.10.30
[BFS] 적록색약  (0) 2019.10.29
[BFS] 아기 상어  (0) 2019.10.24
[BFS] 탈출  (0) 2019.10.24
[BFS] 움직이는 미로 탈출  (0) 2019.10.23