문제
어제 선물을 모두 포장한 민식이는 이제 선물을 배달하려고 한다. 민식이가 선물을 배달할 곳은 이 문제를 읽는 사람들이 앉아 있는 교실이다. 교실은 직사각형모양이고, 모두 같은 크기의 정사각형 블록으로 나누어져 있다.
입력으로 교실의 지도가 주어진다. 각각의 정사각형 블록은 다음과 같이 4가지 종류가 있다.
- S : 지금 민식이가 있는 곳이다. 이곳이 민식이가 배달을 시작하는 곳이다.
- C : 민식이가 반드시 선물을 배달해야 하는 곳이다. 이러한 블록은 정확하게 2개 있다.
- # : 민식이가 갈 수 없는 곳이다.
- . : 민식이가 자유롭게 지나갈 수 있는 곳이다.
민식이가 한 블록 동서남북으로 이동하는데는 1분이 걸린다. 민식이는 네가지 방향 중 하나로 이동할 수 있으며, 교실을 벗어날 수 없다. 민식이가 선물을 배달해야 하는 곳에 들어갈 때, 민식이는 그 곳에 있는 사람 모두에게 선물을 전달해야 한다. 이 상황은 동시에 일어나며, 추가적인 시간이 소요되지 않는다.
민식이는 어느 누구도 자신을 보지 않았으면 하기 때문에, 멈추지 않고 매 시간마다 방향을 바꿔야 한다. 이 말은 같은 방향으로 두 번 연속으로 이동할 수 없다는 말이다. 민식이가 선물을 모두 배달하는데 걸리는 시간의 최솟값을 구하는 프로그램을 작성하시오.
입력
첫째 줄에 교실의 세로 크기 N과 가로 크기 M이 주어진다. N과 M은 50보다 작거나 같은 자연수이다. 둘째 줄부터 N개의 줄에 교실의 지도가 주어진다.
출력
첫째 줄에 민식이가 선물을 모두 배달하는데 걸리는 시간의 최솟값을 출력한다. 만약 불가능 할 때는 -1을 출력한다.
생각대로 dir 지정해서 같은 방향이 아닌 방향으로 이동하게 했는데 같은 지점이라도 방향에 따라 이후 이동 케이스가 다르므로 방향을 visit에 추가해서 시도 했는데 틀렸다.
그 이유는 배달 지점을 방문한 후에 되돌아가는 경로가 필요한데 다른 지점에서 배달도 하지 않고 해당 방향으로 해당 지점을 거쳐가는 케이스가 있다면 visit처리가 되어 이동 불가이기 때문
따라서 visit에 방문 여부도 포함시켜서 해결함.
#include<iostream>
#include<string>
#include<vector>
#include<queue>
using namespace std;
int N, M;
char arr[50][50];
bool visit[2][2][4][50][50];
int dy[4] = { -1,1,0,0 };
int dx[4] = { 0,0,-1,1 };
//북 남 좌 우
struct Node {
int y;
int x;
int dir;
int cost;
bool f1;
bool f2;
};
int main(void)
{
cin >> N >> M;
int y = 0;
int x = 0;
bool pos = false;
for (int i = 0; i < N; i++)
{
for (int j = 0; j < M; j++)
{
cin >> arr[i][j];
if (arr[i][j] == 'S')
{
y = i;
x = j;
arr[i][j] = '.';
}
if (arr[i][j] == 'C' && !pos)
{
arr[i][j] = 'A';
pos = true;
}
if (arr[i][j] == 'C' && pos)
{
arr[i][j] = 'B';
}
}
}
queue<Node> que;
que.push({ y,x,-1,0,0,0 });
while (!que.empty())
{
int y = que.front().y;
int x = que.front().x;
int dir = que.front().dir;
int cost = que.front().cost;
bool f1 = que.front().f1;
bool f2 = que.front().f2;
que.pop();
//cout << "cost : " << cost << " (" << y << "," << x << ") dir : " << dir << endl;
if (arr[y][x] == 'A')
{
//cout << "A" << endl;
f1 = true;
}
if (arr[y][x] == 'B')
{
//cout << "B" << endl;
f2 = true;
}
if (f1 && f2)
{
cout << cost << endl;
return 0;
}
for (int i = 0; i < 4; i++)
{
if (dir != i)
{
int newy = y + dy[i];
int newx = x + dx[i];
if (newy >= 0 && newy < N && newx >= 0 && newx < M)
{
if (!visit[f1][f2][i][newy][newx] && arr[newy][newx] != '#')
{
visit[f1][f2][i][newy][newx] = true;
que.push({ newy,newx,i,cost + 1,f1,f2 });
}
}
}
}
}
cout << -1 << endl;
}
'Algorithm' 카테고리의 다른 글
백준 17088번 등차수열 변환 (0) | 2020.07.27 |
---|---|
백준 16938번 캠프 준비 (0) | 2020.07.23 |
백준 16936번 나3곱2 (0) | 2020.07.22 |
백준 16968번 차량 번호판 1 (0) | 2020.07.22 |
백준 16973번 직사각형 탈출 (0) | 2020.07.22 |