2025.4.4 알고리즘 코드카타

재석 블로그·2025년 4월 4일
0

알고리즘 코드카타 - 111. 무인도 여행

문제 링크

풀이 참고

문제 설명

메리는 여름을 맞아 무인도로 여행을 가기 위해 지도를 보고 있습니다. 지도에는 바다와 무인도들에 대한 정보가 표시돼 있습니다. 지도는 1 x 1크기의 사각형들로 이루어진 직사각형 격자 형태이며, 격자의 각 칸에는 'X' 또는 1에서 9 사이의 자연수가 적혀있습니다. 지도의 'X'는 바다를 나타내며, 숫자는 무인도를 나타냅니다. 이때, 상, 하, 좌, 우로 연결되는 땅들은 하나의 무인도를 이룹니다. 지도의 각 칸에 적힌 숫자는 식량을 나타내는데, 상, 하, 좌, 우로 연결되는 칸에 적힌 숫자를 모두 합한 값은 해당 무인도에서 최대 며칠동안 머물 수 있는지를 나타냅니다. 어떤 섬으로 놀러 갈지 못 정한 메리는 우선 각 섬에서 최대 며칠씩 머물 수 있는지 알아본 후 놀러갈 섬을 결정하려 합니다.

지도를 나타내는 문자열 배열 maps가 매개변수로 주어질 때, 각 섬에서 최대 며칠씩 머무를 수 있는지 배열에 오름차순으로 담아 return 하는 solution 함수를 완성해주세요. 만약 지낼 수 있는 무인도가 없다면 -1을 배열에 담아 return 해주세요.


제한사항

  • 3 ≤ maps의 길이 ≤ 100
  • 3 ≤ maps[i]의 길이 ≤ 100
  • maps[i]는 'X' 또는 1 과 9 사이의 자연수로 이루어진 문자열입니다.
  • 지도는 직사각형 형태입니다.

입출력 예

mapsresult
["X591X","X1X5X","X231X", "1XXX1"][1, 1, 27]
["XXX","XXX","XXX"][-1]

입출력 예 설명
입출력 예 #1

위 문자열은 다음과 같은 지도를 나타냅니다.

연결된 땅들의 값을 합치면 다음과 같으며

이를 오름차순으로 정렬하면 [1, 1, 27]이 됩니다.

입출력 예 #2

위 문자열은 다음과 같은 지도를 나타냅니다.

섬이 존재하지 않기 때문에 -1을 배열에 담아 반환합니다.




풀이 코드

#include <string>
#include <vector>
#include <queue>
#include <algorithm>

using namespace std;

vector<int> solution(vector<string> maps) {
    vector<int> answer;
    int rows = maps.size();
    int cols = maps[0].size();
    vector<vector<bool>> visited(rows, vector<bool>(cols, false));
    
    queue<pair<int, int>> bfsq;
    int dy[4] = {1, -1, 0, 0};
    int dx[4] = {0, 0, 1, -1};
    
    for(int i = 0; i < rows; i++)
    {
        for(int j = 0; j < cols; j++)
        {
            if(maps[i][j] != 'X' && !visited[i][j])
            {
                bfsq.push({i,j});
                visited[i][j] = true;
                int canstay = maps[i][j] - '0';
                
                //BFS 시작
                while(!bfsq.empty())
                {
                    pair<int, int> current = bfsq.front();
                    bfsq.pop();
                    
                    // 섬 상하좌우 탐색
                    int y = current.first;
                    int x = current.second;
                    for(int k = 0; k < 4; k++)
                    {
                        int newy = y + dy[k];
                        int newx = x + dx[k];
                        
                        //탐색 결과 큐에 저장
                        if(newx >= 0 && cols > newx && newy >= 0 && rows > newy && maps[newy][newx] != 'X' && !visited[newy][newx])
                        {
                            visited[newy][newx] = true;
                            canstay += maps[newy][newx] - '0';
                            bfsq.push({newy, newx});
                        }
                    }
                }
                answer.push_back(canstay);
            }
        }
    }
    sort(answer.begin(), answer.end());
    if(answer.empty())
    {
        answer.push_back(-1);
    }
    return answer;
}
  • BFS를 이용하여 풀 수 있는 문제
  • 주어진 maps와 똑같은 크기의 bool배열을 만들어 visited라고 하고, 방문 처리를 할 수 있도록 한다.
  • 이후 BFS 문제와 똑같이, 처음 칸을 큐에 넣고 방문처리를 한다. while문 안에서는 front()를 제거하고 다음 방문할 곳(front() 기준 상하좌우)이 방문했던 곳이 아니라면 큐에 넣는다.
  • 위 과정을 큐가 빌 때까지 반복하면, 현재 있는 섬을 모두 탐색한 것이 되므로 정답 배열에 추가.
  • 이중반복문으로 maps 전체를 탐색하다가, 방문한 적이 없는 섬이 나오면 다시 while문을 반복한다.
  • 정답배열을 오름차순으로 정렬하고, 만약 비어있다면 -1을 넣어 반환하면 끝!



BFS, DFS 문제는 정말 어렵다. 조금만 조건이 복잡해지고 코드가 길어지면 머리에서 일단 버퍼가 걸리고 시작한다. 반복 숙달이 필요한 시점..

profile
게임 개발자 재석의 블로그입니다.

0개의 댓글