- sol1: 매번 O(RC)에 걸처 빙판을 녹임 -> 두 백조가 있는 곳이 연결되었는지 BFS 탐색
#include <bits/stdc++.h>
using namespace std;
int R, C, ans = 0;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
vector<vector<char>> board(1501, vector<char>(1501));
vector<pair<int, int>> Bpos;
bool dir_4_check(int x, int y){
int cnt = 0;
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 || board[nx][ny] == 'X') ++cnt;
}
if(cnt == 4) return true;
else return false;
}
bool bfs(int x, int y, vector<vector<bool>>& visited){
queue<tuple<int, int>> que;
visited[x][y] = true;
que.push({x, y});
while(!que.empty()){
int cx, cy;
tie(cx, cy) = que.front();
if(cx == Bpos[1].first && cy == Bpos[1].second){
return true;
}
que.pop();
for(int i = 0; i < 4; ++i){
int nx = cx + dx[i];
int ny = cy + dy[i];
if(nx < 0 || ny < 0 || nx >= R || ny >= C) continue;
if(visited[nx][ny] || board[nx][ny] == 'X') continue;
visited[nx][ny] = true;
que.push({nx, ny});
}
}
return false;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
cin >> R >> C;
char tmp;
for(int i = 0; i < R; ++i){
for(int j = 0; j < C; ++j){
cin >> tmp;
if(tmp == 'L') {
board[i][j] = '.';
Bpos.push_back({i, j});
}
else{
board[i][j] = tmp;
}
}
}
vector<vector<bool>> visited(R, vector<bool>(C, false));
while(!bfs(Bpos[0].first, Bpos[0].second, visited)){
++ans;
vector<vector<char>> newboard(1501, vector<char>(1501));
for(int i = 0; i < R; ++i){
for(int j = 0; j < C; ++j){
if(board[i][j] == '.' || board[i][j] == 'L'){
newboard[i][j] = board[i][j];
}
else if(board[i][j] == 'X'){
if(dir_4_check(i, j)) {
newboard[i][j] = 'X';
}
else{
newboard[i][j] = '.';
}
}
}
}
board = newboard;
for(int i = 0; i < R; ++i){
for(int j = 0; j < C; ++j){
visited[i][j] = false;
}
}
}
cout << ans;
return 0;
}
- sol2
r, c: 호수 가로, 세로 길이 저장
dx, dy: 네 방향 이동을 위한 배열
waterQ: 빙하 제거를 위한 물의 좌표를 저장
swanQ: 백조가 다닐 수 있는 최전선(물과 빙하의 경계)의 좌표를 저장
swanpos: 백조 두마리의 좌표 저장
lake: 호수 모양 저장(빙하, 물, 백조 위치정보)
ans: 정답
- 아래 과정 무한 반복
- 백조 만남 체크
백조끼리 만난 경우 반복문 탈출
- 시간 증가
- 빙하 녹이기
#include <bits/stdc++.h>
using namespace std;
int r, c, ans = 0;
int dx[4] = {1, 0, -1, 0};
int dy[4] = {0, 1, 0, -1};
int visited[1501][1501];
char lake[1501][1501];
vector<pair<int, int>> swanpos;
queue<pair<int, int>> swanQ, waterQ;
bool check_meet(){
queue<pair<int, int>> tmp;
while(!swanQ.empty()){
int x = swanQ.front().first;
int y = swanQ.front().second;
swanQ.pop();
if(x == swanpos[1].first && y == swanpos[1].second) 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(visited[nx][ny]) continue;
visited[nx][ny] = 1;
if(lake[nx][ny] == 'X') tmp.push({nx, ny});
else swanQ.push({nx, ny});
}
}
swanQ = tmp;
return false;
}
void melt_ice(){
int wsize = waterQ.size();
for(int i = 0; i < wsize; ++i){
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] = '.';
}
}
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0); cout.tie(0);
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}), swanpos.push_back({i, j});
if(lake[i][j] == '.') waterQ.push({i, j});
}
}
swanQ.push({swanpos[0].first, swanpos[0].second});
while(true){
if(check_meet()) break;
++ans;
melt_ice();
}
cout << ans;
}