알고리즘

백준[3197번] 백조와 호수

moongi 2023. 9. 19. 15:21
반응형

참고: https://codecollector.tistory.com/1184

 

(C++) - 백준(BOJ) 3197번 : 백조의 호수

https://www.acmicpc.net/problem/3197 3197번: 백조의 호수 입력의 첫째 줄에는 R과 C가 주어진다. 단, 1 ≤ R, C ≤ 1500. 다음 R개의 줄에는 각각 길이 C의 문자열이 하나씩 주어진다. '.'은 물 공간, 'X'는 빙판

codecollector.tistory.com

생각 못한 부분:

1. 백조의 현재위치도 어쨋든 물일 것이다.

2. 기존에 생각했던 것은 방문위치를 매 번 BFS를 돌릴 때마다 초기화했는데, 그렇게 되면 1500*1500 ~= 대략 200만 이걸 최악의 경우로 가정했을때 1500*1500*1500 => 시간제한에 걸릴 것이다.

아이디어는 참고자료와 비슷하였으나, 백조가 움직일 때 다음 이동이 'X'라면 다음날 이동할 수 있는 것이므로(백조의 현재 위치는 물('.')이기 때문에) 해당 위치들을 저장해두고 다시 BFS를 돌렸으며, 방문위치는 백조가 멈춘위치에서 계속 진행하므로 시간초과도 나지 않을 것이다.

 

해당 코드는 참고 코드를 클론 코딩해보았다. 몇 일 뒤에 다시 스스로 코드를 짜 볼 예정.

#include <iostream>
#include <vector>
#include <queue>
#define pii pair<int, int>
using namespace std;

int r, c, ck[1501][1501], timer;
int dx[] = {0, 0, -1, 1};
int dy[] = {-1, 1, 0, 0};
char lake[1501][1501];

struct Swan
{
    int r, c;
};
vector<Swan> swan;
queue<pii> swanQ, waterQ;

void meltIce()
{
    int wSize = waterQ.size();
    while (wSize--)
    {
        int x = waterQ.front().first;
        int y = waterQ.front().second;
        waterQ.pop();

        for (int i = 0; i < 4; i++)
        {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if (nx < 0 || ny < 0 || nx >= r || ny >= c)
            {
                continue;
            }
            if (lake[nx][ny] != 'X')
            {
                continue;
            }
            waterQ.push({nx, ny});
            lake[nx][ny] = '.';
        }
    }
}

bool canMeet()
{
    queue<pii> s;
    while (!swanQ.empty())
    {
        int x = swanQ.front().first;
        int y = swanQ.front().second;
        swanQ.pop();
        if (x == swan[1].r && y == swan[1].c)
        {
            return true;
        }
        for (int i = 0; i < 4; i++)
        {
            int nx = x + dx[i];
            int ny = y + dy[i];
            if (nx < 0 || ny < 0 || nx >= r || ny >= c)
            {
                continue;
            }
            if (ck[nx][ny])
            {
                continue;
            }
            ck[nx][ny] = true;
            if (lake[nx][ny] == 'X')
            {
                s.push({nx, ny}); // 다음날에 날 수 있다.
            }
            else
            {
                swanQ.push({nx, ny});
            }
        }
    }
    swanQ = s;
    return false;
}
int main(int argc, char const *argv[])
{
    cin >> r >> c;
    for (int i = 0; i < r; i++)
    {
        for (int j = 0; j < c; j++)
        {
            cin >> lake[i][j];
            if (lake[i][j] == 'L')
            {
                waterQ.push({i, j});
                swan.push_back({i, j});
            }
            if (lake[i][j] == '.')
            {
                waterQ.push({i, j});
            }
        }
    }
    swanQ.push({swan[0].r, swan[0].c});
    while (1)
    {
        if (canMeet())
        {
            break;
        }
        timer++;
        meltIce();
    }
    cout << timer;

    return 0;
}
반응형

'알고리즘' 카테고리의 다른 글

백준[15663번] N과 M(9)  (2) 2023.10.31
백준[2133번] 타일 채우기  (0) 2023.10.30
백준[1655번] 가운데를 말해요  (0) 2023.09.19
백준 14889번 스타트와 링크  (0) 2023.09.07
이진 탐색(Binary_search) using python  (0) 2022.12.31