#include <iostream>
#include <vector>
#include <algorithm>
#include <iostream>
#include <string>
#include <queue>
using namespace std;
#define arr_size 20
int dirX[4] = { 1,0,-1,0 };
int dirY[4] = { 0,-1,0,1, };
bool chk[arr_size][arr_size][4][16];//이부분 중요함. 무한루프 벗어나는 조건이 x,y좌표 / 방향 / memory까지 4가지가 완전히 같은 내용 들어왔을 때 루프탄다.
char arr[arr_size][arr_size];
int seperate_row;
int seperate_col;
string sanswer;
void init()
{
int row; cin >> row; seperate_row = row;
int col; cin >> col; seperate_col = col;
for (int i = 0; i < row; i++)
{
for (int j = 0; j < col; j++)
{
char cTemp; cin >> cTemp;
arr[i][j] = cTemp;
}
}
}
void arr_claer()
{
for (int i = 0; i < seperate_row; i++)
{
for (int j = 0; j < seperate_col; j++)
{
arr[i][j] = 0;
}
}
for (int i = 0; i < seperate_row; i++)
{
for (int j = 0; j < seperate_col; j++)
{
for (int k = 0; k < 4; k++)
{
for (int l = 0; l < 16; l++)
{
chk[i][j][k][l] = false;
}
}
}
}
}
void bfs()
{
queue<pair<pair<int, int>, pair<int, int>>> qTemp;//y,x,방향,memory내용
qTemp.push(make_pair(make_pair(0, 0), make_pair(0, 0)));
chk[0][0][0][0] = true;//방문기록을 위한 함수내용입니다.
while (!qTemp.empty())
{
int nowy = qTemp.front().first.first;
int nowx = qTemp.front().first.second;
int dir = qTemp.front().second.first;
int mem = qTemp.front().second.second;
qTemp.pop();
if (arr[nowy][nowx] == '@') //만약 @기호를 만나게 된다면 YES이다.
{
sanswer = "YES";
return;
}
int next_dir = dir;
int next_mem = mem;
char cTemp = arr[nowy][nowx];
if (cTemp == '<') next_dir = 2;
else if (cTemp == '>') next_dir = 0;
else if (cTemp == '^') next_dir = 1;
else if (cTemp == 'v') next_dir = 3;
else if (cTemp == '_') next_dir = mem == 0 ? 0 : 2;
else if (cTemp == 'ㅣ') next_dir = mem == 0 ? 3 : 1;
else if (cTemp == '+') next_mem = mem == 15 ? 0 : mem + 1;
else if (cTemp == '-') next_mem = mem == 0 ? 15 : mem - 1;
else if (cTemp >= '0' && cTemp <= '9') next_mem = cTemp - '0';
if (cTemp == '?')//물음표 떳을땐 랜덤 동서남북 전진입니다.
{
for (int i = 0; i < 4; i++)
{
int nexty = nowy + dirY[i];
int nextx = nowx + dirX[i];
//원래 이 부분에 바운더리 조건이 들어가야하는데.
if (nexty < 0) nexty = seperate_row - 1;
else if (nexty == seperate_row - 1) nexty = 0;
if (nextx < 0) nextx = seperate_col - 1;
else if (nextx == seperate_col - 1) nextx = 0;
//경계도달했을때 처리하는 바운더리입니다.
if (chk[nexty][nextx][i][next_mem] == false)
{
chk[nexty][nextx][i][next_mem] = true;
qTemp.push(make_pair(make_pair(nexty, nextx), make_pair(i, next_mem)));
}
}
}
else
{
int nexty = nowy + dirY[next_dir];
int nextx = nowx + dirX[next_dir];
//원래 이 부분에 바운더리 조건이 들어가야하는데.
if (nexty < 0) nexty = seperate_row - 1;
else if (nexty == seperate_row ) nexty = 0;
if (nextx < 0) nextx = seperate_col - 1;
else if (nextx == seperate_col ) nextx = 0;
//경계도달했을때 처리하는 바운더리입니다.
if (chk[nexty][nextx][next_dir][next_mem] == false)
{
chk[nexty][nextx][next_dir][next_mem] = true;
qTemp.push(make_pair(make_pair(nexty, nextx), make_pair(next_dir, next_mem)));
}
}
}
sanswer = "NO";
}
int main()
{
int test_case; cin >> test_case;
for (int test = 1; test <= test_case; test++)
{
arr_claer();
init();
bfs();
cout << "#" << test<<" "<<sanswer << endl;
sanswer = "";
}
}
답지는
https://yabmoons.tistory.com/454
1.원래 BFS 쓸 때 그냥 바운더리 내 조건만 확인했는데
이 문제에서 방향을 정해줬다. 따라서 남으로갈때
diry = 1, dirx = 0;인거 인식해줘야함. y에 -1넣으면 진행안된다.
2.4차원배열 다루기.
배열의 BFS chk 배열에서, 세부정보를 위해 3차원 이상도 다룰 수 있음.
//원래 이 부분에 바운더리 조건이 들어가야하는데.
if (nexty < 0) nexty = seperate_row - 1;
else if (nexty == seperate_row - 1) nexty = 0;
if (nextx < 0) nextx = seperate_col - 1;
else if (nextx == seperate_col - 1) nextx = 0;
//경계도달했을때 처리하는 바운더리입니다.
바운더리 넘쳤을때 기존엔 continue였는데 다른식의 처리.
1 2 익히기.