프로그래머스
코드 중심의 개발자 채용. 스택 기반의 포지션 매칭. 프로그래머스의 개발자 맞춤형 프로필을 등록하고, 나와 기술 궁합이 잘 맞는 기업들을 매칭 받으세요.
programmers.co.kr
📄 문제
메리는 여름을 맞아 무인도로 여행을 가기 위해 지도를 보고 있습니다. 지도에는 바다와 무인도들에 대한 정보가 표시돼 있습니다. 지도는 1 x 1크기의 사각형들로 이루어진 직사각형 격자 형태이며, 격자의 각 칸에는 'X' 또는 1에서 9 사이의 자연수가 적혀있습니다. 지도의 'X'는 바다를 나타내며, 숫자는 무인도를 나타냅니다. 이때, 상, 하, 좌, 우로 연결되는 땅들은 하나의 무인도를 이룹니다. 지도의 각 칸에 적힌 숫자는 식량을 나타내는데, 상, 하, 좌, 우로 연결되는 칸에 적힌 숫자를 모두 합한 값은 해당 무인도에서 최대 며칠동안 머물 수 있는지를 나타냅니다. 어떤 섬으로 놀러 갈지 못 정한 메리는 우선 각 섬에서 최대 며칠씩 머물 수 있는지 알아본 후 놀러갈 섬을 결정하려 합니다.
지도를 나타내는 문자열 배열 maps가 매개변수로 주어질 때, 각 섬에서 최대 며칠씩 머무를 수 있는지 배열에 오름차순으로 담아 return 하는 solution 함수를 완성해주세요. 만약 지낼 수 있는 무인도가 없다면 -1을 배열에 담아 return 해주세요.
📝 풀이
· BFS 구현
#include <string>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
int dx[4]{ -1, 1, 0, 0 };
int dy[4]{ 0, 0, -1, 1 };
vector<int> solution(vector<string> maps) {
int height = maps.size();
int width = maps[0].size();
queue<pair<int, int>> q;
vector<vector<bool>> v(vector<vector<bool>>(height, vector<bool>(width, false)));
vector<int> answer;
for (int i = 0; i < height; ++i)
for (int j = 0; j < width; ++j)
if (maps[i][j] != 'X' && !v[i][j])
{
int sum = 0;
q.push({ i, j });
v[i][j] = true;
while (!q.empty())
{
int x = q.front().second;
int y = q.front().first;
q.pop();
sum += (maps[y][x] - '0');
for (int k = 0; k < 4; ++k)
{
int xx = x + dx[k];
int yy = y + dy[k];
if (xx == -1 || yy == -1 || xx == width || yy == height || maps[yy][xx] == 'X' || v[yy][xx])
continue;
v[yy][xx] = true;
q.push({ yy, xx });
printf("{%d %d}에서 {%d %d}로 이동!\n", y, x, yy, xx);
}
}
answer.push_back(sum);
}
sort(answer.begin(), answer.end());
if (answer.empty())
answer.push_back(-1);
return answer;
}
- 큐를 이용한 BFS로 문제를 해결하였습니다.
- 모든 map을 검사하여 방문하지 않았고, 'X'가 아닌경우 BFS를 시작합니다.
- BFS에서 현재 위치를 기준으로 모든 방향을 검사하여 갈 수 있는 곳이라면 해당 위치의 식량 값 숫자를 누적하여 큐가 비어 빠져나올때 그 값을 answer에 삽입합니다.
· DFS 구현
#include <string>
#include <vector>
#include <queue>
#include <algorithm>
using namespace std;
int dx[4]{ -1, 1, 0, 0 };
int dy[4]{ 0, 0, -1, 1 };
int width, height, sum;
vector<vector<bool>> visit;
vector<int> answer;
// DFS
void DFS(vector<string> maps, int food, int y, int x)
{
sum += food;
for (int i = 0; i < 4; ++i)
{
int yy = y + dy[i];
int xx = x + dx[i];
if (xx == -1 || yy == -1 || xx == width || yy == height || maps[yy][xx] == 'X' || visit[yy][xx])
continue;
visit[yy][xx] = true;
DFS(maps, maps[yy][xx] - '0', yy, xx);
}
}
vector<int> solution(vector<string> maps) {
height = maps.size();
width = maps[0].size();
queue<pair<int, int>> q;
visit = vector<vector<bool>>(height, vector<bool>(width, false));
for (int i = 0; i < height; ++i)
for (int j = 0; j < width; ++j)
if (!visit[i][j] && maps[i][j] != 'X')
{
sum = 0;
visit[i][j] = true;
DFS(maps, maps[i][j] - '0', i, j);
answer.push_back(sum);
}
sort(answer.begin(), answer.end());
if (answer.empty())
answer.push_back(-1);
return answer;
}
- 재귀를 이용한 DFS로 구현한 방법입니다.
- BFS와 같은 방법으로, 현재 위치를 기준으로 갈 수 있는 모든 방향을 더하여 검사합니다.
- sum에 이동한 곳의 식량 값 숫자를 누적하여 DFS가 완전히 끝나면 해당 값을 answer에 삽입합니다.
'algorithms (C++)' 카테고리의 다른 글
[C++][프로그래머스] 시소 짝꿍 (1) | 2023.11.01 |
---|---|
[C++][프로그래머스] 뒤에 있는 큰 수 찾기 (0) | 2023.11.01 |
[C++][프로그래머스] 호텔 대실 🔥 (0) | 2023.10.30 |
[C++][프로그래머스] 리코쳇 로봇 (0) | 2023.10.29 |
[C++][프로그래머스] 광물 캐기 (0) | 2023.10.29 |