PS

백준 2151번 거울 설치

남마허 2020. 3. 7. 00:32

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

 

2151번: 거울 설치

첫째 줄에 집의 크기 N (2 ≤ N ≤ 50)이 주어진다. 다음 N개의 줄에는 N개의 문자로 집에 대한 정보가 주어진다. ‘#’는 문이 설치된 곳으로 항상 두 곳이며, ‘.’은 아무 것도 없는 것으로 빛은 이 곳을 통과한다. ‘!’은 거울을 설치할 수 있는 위치를 나타내고, ‘*’은 빛이 통과할 수 없는 벽을 나타낸다.

www.acmicpc.net

 

 

 

 

 

 

<접근방법>

완전 탐색 문제입니다.

거울을 설치할 수 있는 곳에 4가지 방법으로 설치 or 그냥 지나가기를 해줍니다.

 

dfs, bfs 둘 다 가능한 방법이지만 저는 bfs로 하였습니다.

bfs로 하면서 방문 체크를 해줘야합니다.

단순히 좌표로만 방문 체크를 해주면 방향처리가 안됩니다.

같은 지점이라도 방향에 따라 결과가 달라지기 때문에 나가는 방향에 따라서 방문 체크를 해줘야합니다.

 

또 최단거리 탐색과는 다르게 가중치가 거울의 사용횟수 입니다.

그러므로 우선순위 큐를 사용하여 사용한 거울의 갯수가 작은 순서대로 정렬시킵니다.

그러면 가장 먼저 다른 문에 도달했을 때가 정답이 됩니다.

 

<느낀 점>

 

 

 


 

 

 

<코드>

#include <iostream>
#include <algorithm>
#include <queue>
#include <vector>
using namespace std;

struct point {
	int y, x, d, cnt;
};

int n, res = 2501;
char map[51][51];
bool visit[50][50][4];
int dy[4] = {0, -1, 0, 1 };
int dx[4] = {1, 0, -1, 0 };
int sy, sx;

struct cmp {
	bool operator()(point a, point b) {
		return a.cnt > b.cnt;
	}
};

priority_queue<point, vector<point>, cmp> q;

void bfs() {
	while (!q.empty()) {
		point t = q.top();
		q.pop();

		if (map[t.y][t.x] == '#' && !(t.y == sy && t.x == sx)) {
			cout << t.cnt << '\n';
			exit(0);
		}

		int ty = t.y + dy[t.d];
		int tx = t.x + dx[t.d];
		int td;
		int tcnt = t.cnt + 1;

		if (ty < 0 || ty >= n || tx < 0 || tx >= n ||
			map[ty][tx] == '*') continue;

		//그냥 가기
		if (!visit[ty][tx][t.d]) {
			q.push({ ty, tx, t.d, t.cnt });
			visit[ty][tx][t.d] = true;
		}

		if (map[ty][tx] == '!') {
			if (t.d == 0) {
				td = 1;
				if (!visit[ty][tx][td]) {
					q.push({ ty, tx, td, tcnt });
					visit[ty][tx][td] = true;
				}

				td = 3;
				if (!visit[ty][tx][td]) {
					q.push({ ty, tx, td, tcnt });
					visit[ty][tx][td] = true;
				}
			}
			if (t.d == 1) {
				td = 0;
				if (!visit[ty][tx][td]) {
					q.push({ ty, tx, td, tcnt });
					visit[ty][tx][td] = true;
				}

				td = 2;
				if (!visit[ty][tx][td]) {
					q.push({ ty, tx, td, tcnt });
					visit[ty][tx][td] = true;
				}
			}
			if (t.d == 2) {
				td = 1;
				if (!visit[ty][tx][td]) {
					q.push({ ty, tx, td, tcnt });
					visit[ty][tx][td] = true;
				}

				td = 3;
				if (!visit[ty][tx][td]) {
					q.push({ ty, tx, td, tcnt });
					visit[ty][tx][td] = true;
				}
			}
			if (t.d == 3) {
				td = 0;
				if (!visit[ty][tx][td]) {
					q.push({ ty, tx, td, tcnt });
					visit[ty][tx][td] = true;
				}

				td = 2;
				if (!visit[ty][tx][td]) {
					q.push({ ty, tx, td, tcnt });
					visit[ty][tx][td] = true;
				}
			}
		}
	}
}

int main() {
	cin >> n;
	for (int i = 0; i < n; i++) {
		for (int j = 0; j < n; j++) {
			cin >> map[i][j];
			if (map[i][j] == '#') {
				sy = i; sx = j;
			}
		}
	}

	for (int i = 0; i < 4; i++) {
		q.push({sy, sx, i, 0});
		visit[sy][sx][i] = true;
	}
	
	bfs();

	return 0;
}

 

 

 

 

 

 

 

반응형