https://www.acmicpc.net/problem/3197
3197번: 백조의 호수
입력의 첫째 줄에는 R과 C가 주어진다. 단, 1 ≤ R, C ≤ 1500. 다음 R개의 줄에는 각각 길이 C의 문자열이 하나씩 주어진다. '.'은 물 공간, 'X'는 빙판 공간, 'L'은 백조가 있는 공간으로 나타낸다.
www.acmicpc.net
[문제]
두 마리의 백조가 호수에서 살고 있었다. 그렇지만 두 마리는 호수를 덮고 있는 빙판으로 만나지 못한다.
호수는 행이 R개, 열이 C개인 직사각형 모양이다. 어떤 칸은 얼음으로 덮여있다.
호수는 차례로 녹는데, 매일 물 공간과 접촉한 모든 빙판 공간은 녹는다. 두 개의 공간이 접촉하려면 가로나 세로로 닿아 있는 것만 (대각선은 고려하지 않는다) 생각한다.
백조는 오직 물 공간에서 세로나 가로로만(대각선은 제외한다) 움직일 수 있다.
며칠이 지나야 백조들이 만날 수 있는 지 계산하는 프로그램을 작성하시오.
[입력]
입력의 첫째 줄에는 R과 C가 주어진다. 단, 1 ≤ R, C ≤ 1500.
다음 R개의 줄에는 각각 길이 C의 문자열이 하나씩 주어진다. '.'은 물 공간, 'X'는 빙판 공간, 'L'은 백조가 있는 공간으로 나타낸다.
[출력]
첫째 줄에 문제에서 주어진 걸리는 날을 출력한다.
[풀이]
처음 풀 때 현재 맵을 새로운 맵에 복사해서 푸는 방식으로 풀었더니 시간 초과가 났습니다.
아래 코드는 백조의 위치를 벡터에 담고 물의 위치를 모두 water 큐에 담습니다.
여기서 큐를 하나 더 사용하는데 이 nq는 백조의 다음 시작 위치를 담는 큐입니다.
즉, 백조가 물을 떠다니다가 X라는 벽을 만나면 다음날 이 벽은 녹고 그 위치부터 백조가 BFS를 진행해서 다른 백조를 만나는 것입니다.
[코드]
#include<bits/stdc++.h>
#define Y first
#define X second
using namespace std;
int dx[4] = {1,-1,0,0};
int dy[4] = {0,0,1,-1};
int r,c;
string lake_map[1501];
bool vst[1501][1501];
vector<pair<int,int>> swan;
queue<pair<int,int>> water;
int main(void){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> r >> c;
for(int i=0; i< r; i++){
cin >> lake_map[i];
for(int j=0; j<c; j++){
if(lake_map[i][j] == 'L'){
swan.push_back({i,j});
lake_map[i][j] = '.';
water.push({i,j});
}
else if(lake_map[i][j] == '.') water.push({i,j});
}
}
queue<pair<int,int>> q;
int day =0;
q.push(swan[0]);
vst[swan[0].Y][swan[0].X] = 1;
while(1){
queue<pair<int,int>> nq;
while(!q.empty()){
auto cur = q.front();
q.pop();
for(int dir= 0; dir<4; dir++){
int nx = cur.X + dx[dir];
int ny = cur.Y + dy[dir];
if(nx < 0 || ny < 0 || nx >= c || ny >= r || vst[ny][nx]) continue;
else if(swan[1].X == nx && swan[1].Y == ny){
cout << day;
return 0;
}
else if(lake_map[ny][nx] == 'X') nq.push({ny,nx});
else q.push({ny,nx});
vst[ny][nx] = 1;
}
}
q = nq;
day++;
int ws = water.size();
while(ws--){
auto cur = water.front();
water.pop();
for(int dir=0; dir<4; dir++){
int nx = cur.X + dx[dir];
int ny = cur.Y + dy[dir];
if(nx < 0 || ny < 0 || nx >= c || ny >= r) continue;
else if(lake_map[ny][nx] == 'X'){
water.push({ny,nx});
lake_map[ny][nx] = '.';
}
}
}
}
return 0;
}
'백준 알고리즘 > {BFS,DFS}' 카테고리의 다른 글
[백준] 13913 c++ 숨바꼭질 4 (0) | 2021.10.22 |
---|---|
[백준] 1600 c++ 말이 되고픈 원숭이 (0) | 2021.10.21 |
[백준] 13549 c++ 숨바꼭질 3 (0) | 2021.10.20 |
[백준] 2573 c++ 빙산 (0) | 2021.10.20 |