Programmers 154540. 무인도여행
문제 풀이 과정을 공유하고자 한다.
문제 출처
1. 문제설명
- 최대 100 크기의 정사각형 지도가 주어진다.
- 각 칸은
X
또는 1~9까지의 숫자 중 하나이며 각각 바다, 무인도를 나타낸다. - 상,하,좌,우로 연결되는 땅들은 하나의 무인도를 이룬다고 가정
- 칸에 적힌 숫자를 모두 합한 값은 해당 무인도에서 최대 며칠동안 머물 수 있는지를 나타낸다.
- 각 섬에서 최대 며칠씩 머물 수 있는지 알아보자
- 섬이 여러개라면, 오름차순으로 정렬
- 섬이 없다면, -1
2. 알고리즘 설계
- 맵의 전체를 탐색하면서 숫자가 아닌 칸을 BFS 탐색한다.
- 탐색 중에 방문한 점은
visited
를 이용해 체크한다.
- 탐색 중에 방문한 점은
3. 로직
- BFS 탐색 영역을 모두 더해야 한다.
visited
에서 체크된 영역은 건너뛰고,- 그 외에 한번 지나간 영역은 변수에 더해준다.
- BFS가 한번 수행될 때마다, 무인도 영역을 하나씩 탐색한 것
- 따라서 BFS 리턴 값을 벡터에 누적시킨다.
- 오름차순으로 출력해야하므로, 정렬된 벡터를
sort
4. 전체 코드
#include <iostream>
#include <vector>
#include <string>
#include <queue>
#include <algorithm>
using namespace std;
using pii = pair<int, int>;
const int dy[] = { -1,1,0,0 };
const int dx[] = { 0,0,-1,1 };
bool visited[100][100] = { false, };
int x_len, y_len;
int bfs(vector<string> maps, int sy, int sx, int cost)
{
int ret = 0;
queue<pii> q;
q.push({ sy, sx });
visited[sy][sx] = true;
ret += cost;
while (!q.empty()) {
pii cur = q.front();
q.pop();
for (int dir = 0; dir < 4; dir++) {
int ny = cur.first + dy[dir];
int nx = cur.second + dx[dir];
if (ny < 0 || nx < 0 || ny >= y_len || nx >= x_len)
continue;
if (maps[ny][nx] != 'X' && !visited[ny][nx]) {
q.push({ ny,nx });
visited[ny][nx] = true;
ret += (maps[ny][nx] - '0');
}
}
}
return ret;
}
vector<int> solution(vector<string> maps)
{
vector<int> ret;
y_len = maps.size();
x_len = maps[0].size();
for (int y = 0; y < y_len; y++) {
for (int x = 0; x < x_len; x++) {
if (maps[y][x] != 'X' && !visited[y][x]) {
int temp = bfs(maps, y, x, (maps[y][x] - '0'));
ret.push_back(temp);
}
}
}
sort(ret.begin(), ret.end());
return (ret.size() ? ret : vector<int>{-1});
}
5. 소감
- 프로그래머스 2단계 안 푼 문제 순서대로 풀이하고 있는데,
- BFS 관련 문제가 대부분이다.
- BFS는 어느정도 풀이가 가능하니,
- 우선은 다른 유형의 알고리즘(DP, Greedy 등)부터 풀이해야겠다.