알고리즘 :: 큰돌 :: Chapter 3 - 완전탐색/백트래킹 :: 백준 2589 보물섬

Embedded June·2023년 7월 6일
0
post-thumbnail

문제

문제 링크

해설

  • 보물의 위치가 주어지고, 시작 위치에서 보물까지 최단거리를 구하는 일반적인 문제와 달리 이 문제는 시작위치와 도착위치가 정해져있지 않습니다.
  • 그러므로 임의의 육지 상 좌표에 대해 BFS를 수행해 갈 수 있는 모든 좌표의 최단거리를 구하고 그 중 가장 긴 거리를 구하면 해당 지점을 시작지점으로, 가장 긴 거리의 좌표를 보물의 위치로 삼으면 됩니다.
  • 이 아이디어만 떠올렸다면 나머지는 정말 간단합니다.
    • 입력받은 문자열 중 ‘W’ 문자에 대한 좌표를 모두 따로 저장합니다.
    • 모든 육지 좌표에 대해 BFS를 수행하고, 가장 긴 보물의 위치를 구합니다.
    • 매 BFS 수행 후에는 memset() 또는 fill() 함수를 이용해 visited 표시를 초기화해야 하는 것을 잊지 맙시다.

코드

#include <iostream>
#include <vector>
#include <queue>
#include <tuple>
#include <cstring>
using namespace std;

constexpr int d[4][2] = {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};

int N, M, answer;
bool map[52][52];
bool visited[52][52];
vector<pair<int, int>> lands_pos;

void BFS(int sy, int sx) {
    queue<tuple<int, int, int>> q;
    q.emplace(sy, sx, 0);
    visited[sy][sx] = true;

    while (!q.empty()) {
        int cy, cx, cd;
        tie(cy, cx, cd) = q.front();
        q.pop();
        answer = max(answer, cd);
        for (auto i : d) {
            int ny = cy + i[0], nx = cx + i[1];
            if (map[ny][nx] && !visited[ny][nx]) {
                q.emplace(ny, nx, cd + 1);
                visited[ny][nx] = true;
            }
        }
    }
}

int main() {
    ios::sync_with_stdio(false), cin.tie(nullptr), cout.tie(nullptr);
    cin >> N >> M;
    lands_pos.reserve(N * M);
    for (int y = 1; y <= N; y++) {
        string row;
        cin >> row;
        for (int x = 1; x <= M; x++) {
            if (row[x - 1] == 'L') {
                map[y][x] = true;
                lands_pos.emplace_back(y, x);
            }
        }
    }
    for (int i = 0; i < lands_pos.size(); i++) {
        BFS(lands_pos[i].first, lands_pos[i].second);
        memset(visited, false, sizeof(visited));
    }
    cout << answer << '\n';
    return 0;
}

소스코드 링크

결과

profile
임베디드 시스템 공학자를 지망하는 컴퓨터공학+전자공학 복수전공 학부생입니다. 타인의 피드백을 수용하고 숙고하고 대응하며 자극과 반응 사이의 간격을 늘리며 스스로 반응을 컨트롤 할 수 있는 주도적인 사람이 되는 것이 저의 20대의 목표입니다.

0개의 댓글