본문 바로가기
백준 알고리즘/BFS

백준 구슬 탈출 2 C++

by paysmile 2019. 10. 18.

#include <iostream>
#include <queue>
#include <cstring>

using namespace std;
const int MAX = 11;
char board[MAX][MAX];
int n, m;
pair<int, int> r, b, hole;
int visited[MAX][MAX][MAX][MAX];
int answer = -1;

struct Move {
	int x, y;
};
Move mv[4] = { {1,0},{-1,0},{0,1},{0,-1} };

void bfs() {
	memset(visited, -1, sizeof(visited));

	queue <pair<int,pair<pair<int, int>, pair<int, int>>>> q;
	q.push(make_pair(0,make_pair(r, b)));
	visited[r.first][r.second][b.first][b.second] = 1;

	while (!q.empty()) {
		int ri = q.front().second.first.first;
		int rj = q.front().second.first.second;
		int bi = q.front().second.second.first;
		int bj = q.front().second.second.second;
		int count = q.front().first;
		q.pop();

		if (count >= 10)
			return;

		//cout << endl;
		//cout << count+1 << endl;
		for (int k = 0; k < 4; k++) {
			int moveri = ri;
			int moverj = rj;
			int movebi = bi;
			int movebj = bj;
			bool redhole = false;
			bool bluehole = false;

			int flag = 0;
			if (k == 0) {
				if (ri >= bi)
					flag = 1;
			}
			if (k == 1) {
				if (ri < bi)
					flag = 1;
			}
			if (k == 2) {
				if (rj >= bj)
					flag = 1;
			}
			if (k == 3) {
				if (rj < bj)
					flag = 1;
			}
			if (flag == 1) {
				//redfirst
				while (true) {
					if (make_pair(moveri, moverj) == hole) {
						redhole = true;
						break;
					}
					if (!(moveri+mv[k].x >= 0 && moveri + mv[k].x < n && moverj+mv[k].y >= 0 && moverj + mv[k].y < m && board[moveri+mv[k].x][moverj+mv[k].y] != '#'))
						break;
					moveri += mv[k].x;
					moverj += mv[k].y;
				}

				while (true) {
					if (make_pair(movebi, movebj) == hole ) {
						bluehole = true;
						break;
					}
					if ((moveri == movebi + mv[k].x && moverj == movebj + mv[k].y) && redhole == true) {
						bluehole = true;
						break;
					}
					if (!(movebi + mv[k].x >= 0 && movebi + mv[k].x < n && movebj + mv[k].y >= 0 && movebj + mv[k].y<m && board[movebi+mv[k].x][movebj+mv[k].y] != '#') || (moveri== movebi + mv[k].x && moverj== movebj + mv[k].y))
						break;
					movebi += mv[k].x;
					movebj += mv[k].y;
				}
			}
			else {
				//bluefirst
				while (true) {
					if (make_pair(movebi, movebj) == hole) {
						bluehole = true;
						break;
					}
					if (!(movebi + mv[k].x >= 0 && movebi + mv[k].x < n && movebj + mv[k].y >= 0 && movebj + mv[k].y<m && board[movebi+mv[k].x][movebj+mv[k].y] != '#'))
						break;
					movebi += mv[k].x;
					movebj += mv[k].y;
				}

				while (true) {
					if (make_pair(moveri, moverj) == hole) {
						redhole = true;
						break;
					}
					if ((moveri + mv[k].x == movebi && moverj + mv[k].y == movebj) && bluehole == true) {
						bluehole = true;
						break;
					}
					if (!(moveri + mv[k].x >= 0 && moveri + mv[k].x < n && moverj + mv[k].y >= 0 && moverj + mv[k].y<m && board[moveri+mv[k].x][moverj+mv[k].y] != '#')|| (moveri + mv[k].x == movebi && moverj + mv[k].y == movebj))
						break;
					moveri += mv[k].x;
					moverj += mv[k].y;
				}
			}
			//cout << moveri << " " << moverj << " " << movebi << " " << movebj << endl;
			if (redhole == true && bluehole == false) {
				answer = count + 1;
				return;
			}
			if (redhole == false && bluehole == false && visited[moveri][moverj][movebi][movebj] == -1) {
				//cout <<"큐 들어감 "<< moveri << " " << moverj << " " << movebi << " " << movebj << endl;
				q.push(make_pair(count + 1, make_pair(make_pair(moveri, moverj), make_pair(movebi, movebj))));
				visited[moveri][moverj][movebi][movebj] = 1;
			}
		}
	}
	return;
}

int main(void) {
	cin >> n >> m;

	for (int i = 0; i < n; i++) {
		for (int j = 0; j < m; j++) {
			cin >> board[i][j];
			if (board[i][j] == 'R')
				r = make_pair(i, j);
			else if(board[i][j] == 'B')
				b = make_pair(i, j);
			else if(board[i][j] == 'O')
				hole = make_pair(i, j);
		}
	}
	bfs();
	cout << answer << endl;
	return 0;
}

'백준 알고리즘 > BFS' 카테고리의 다른 글

아기상어 C++  (0) 2021.01.03
연구소 C++  (0) 2020.11.16
백준 연구소3 C++  (0) 2019.10.18
백준 16234번 C++  (0) 2019.10.09
백준 5427번 C++  (0) 2019.08.21