프로그래머스 미로 탈출 C++
2023. 10. 21. 18:35ㆍ알고리즘
#include <string>
#include <vector>
#include <queue>
using namespace std;
struct Maze {
int x;
int y;
bool lever;
};
int visited[101][101];
int dx[4] = { -1, 1, 0, 0 };
int dy[4] = { 0, 0, -1, 1 };
int solution(vector<string> maps) {
int answer = 0;
int sx, sy;
//find starting point
int col = maps.size();
int row = maps[0].size();
for (int i = 0; i < col;i++) {
for (int j = 0; j < row ;j++) {
if (maps[i][j] == 'S') {
sx = j, sy = i;
break;
}
}
}
queue<Maze> q;
q.push({ sx, sy, false });
visited[sy][sx] = 1;
// bfs
while (!q.empty()) {
int cx = q.front().x;
int cy = q.front().y;
int clever = q.front().lever;
q.pop();
if (clever == true && maps[cy][cx] == 'E') {
return visited[cy][cx]-1;
}
for (int i = 0;i < 4;i++) {
int nx = cx + dx[i];
int ny = cy + dy[i];
bool nlever = clever;
if (ny < 0 || nx < 0 || ny >= col || nx >= row) {
continue;
}
if (visited[ny][nx]!=0){
continue;
}
if (maps[ny][nx] == 'X') {
continue;
}
if (maps[ny][nx] == 'L') {
nlever = true;
}
visited[ny][nx] = visited[cy][cx] + 1;
q.push({ nx, ny, nlever });
}
}
answer = -1;
return answer;
}
초기 코드는 이렇게 짰는데 절반만 맞았다.
제한 사항에 이런 구절이 있다.
모든 통로, 출구, 레버, 시작점은 여러 번 지나갈 수 있습니다.
이 부분에 대한 처리가 이 문제의 핵심 구현 사항이다.
이렇게 하면 visited에 대한 처리가 모호해진다. 따라서, bfs를 두번 돌리는 것이 조금 더 맞는 구현이라고 볼 수 있다.
정답 코드 :
#include <string>
#include <vector>
#include <queue>
#include <cstring>
#include <iostream>
using namespace std;
struct Maze {
int x;
int y;
};
int visited[101][101];
int dist;
int dx[4] = { -1, 1, 0, 0 };
int dy[4] = { 0, 0, -1, 1 };
int solution(vector<string> maps) {
int answer = 0;
int sx, sy;
bool found_lever = false, found_exit = false;
//find starting point
int col = maps.size();
int row = maps[0].size();
for (int i = 0; i < col;i++) {
for (int j = 0; j < row;j++) {
if (maps[i][j] == 'S') {
sx = j, sy = i;
break;
}
}
}
queue<Maze> q;
q.push({ sx, sy });
visited[sy][sx] = 1;
// bfs
while (!q.empty()) {
int cx = q.front().x;
int cy = q.front().y;
q.pop();
for (int i = 0;i < 4;i++) {
int nx = cx + dx[i];
int ny = cy + dy[i];
if (ny < 0 || nx < 0 || ny >= col || nx >= row) {
continue;
}
if (maps[ny][nx] == 'X') {
continue;
}
if (visited[ny][nx] != 0) {
continue;
}
visited[ny][nx] = visited[cy][cx] + 1;
if (maps[ny][nx] == 'L') {
sx = nx, sy = ny, dist = visited[ny][nx] - 1;
found_lever = true;
break;
}
q.push({ nx, ny });
}
}
while (!q.empty()) {
q.pop();
}
memset(visited, 0, sizeof(visited));
q.push({ sx, sy });
visited[sy][sx] = 1;
while (!q.empty()) {
int cx = q.front().x;
int cy = q.front().y;
q.pop();
for (int i = 0;i < 4;i++) {
int nx = cx + dx[i];
int ny = cy + dy[i];
if (ny < 0 || nx < 0 || ny >= col || nx >= row) {
continue;
}
if (maps[ny][nx] == 'X') {
continue;
}
if (visited[ny][nx] != 0) {
continue;
}
visited[ny][nx] = visited[cy][cx] + 1;
if (maps[ny][nx] == 'E') {
sx = nx, sy = ny, dist = dist + visited[ny][nx] - 1;
found_exit = -1;
break;
}
q.push({ nx, ny });
}
}
if (!found_lever || !found_exit){
answer = -1;
}
else{
answer = dist;
}
return answer;
}
'알고리즘' 카테고리의 다른 글
프로그래머스 폰켓몬 c++ unordered_map 해시 (0) | 2023.10.25 |
---|---|
프로그래머스 N-Queen dfs backtracking C++ (0) | 2023.10.24 |
프로그래머스 카펫 C++ (0) | 2023.10.20 |
프로그래머스 피로도 C++ (0) | 2023.10.20 |
프로그래머스 모의고사 C++ (0) | 2023.10.19 |