BOJ 3197 백조의 호수

2020. 12. 1. 17:07·알고리즘/BOJ

www.acmicpc.net/problem/3197

 

3197번: 백조의 호수

입력의 첫째 줄에는 R과 C가 주어진다. 단, 1 ≤ R, C ≤ 1500. 각 R줄 동안 C만큼의 문자열이 주어진다. '.'은 물 공간, 'X'는 빙판 공간, 'L'은 백조가 있는 공간으로 나타낸다.

www.acmicpc.net

 

처음 문제를 봤을 때 맵의 크기가 1500*1500 이길래 BFS두 개를 배열 초기화를 해가면서 사용해도

1초 안에 돌아갈까? 생각해서 구현해봤지만 TLE가 났다.

정 모르겠어서 찾아봤는데 물에 대해서 큐에 집어 넣어주고, nextQ에 넣어준 뒤에

Q = nextQ 를 통해서 복사가 가능했다..!

그리고 백조에 대해서 BFS를 해줘야 하는데 중간에 다른 백조가 있다면 BFS의 반환 값을

참으로 반환해준다.

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
#include <iostream>
#include <queue>
#include <vector>
using namespace std;
 
queue<pair<int, int>> q, sq, nsq;
vector<pair<int, int>> swan;
char a[1501][1501];
bool vis[1501][1501];
int dx[4] = { 1,0,-1,0 };
int dy[4] = { 0,1,0,-1 };
int n, m, ans;
 
bool bfs() {
    while (!sq.empty()) {
        auto cur = sq.front(); sq.pop();
        if (cur.first == swan[1].first && cur.second == swan[1].second) return true;
        for (int i = 0; i < 4; ++i) {
            int nx = cur.first + dx[i];
            int ny = cur.second + dy[i];
            if (nx < 0 || nx >= n || ny < 0 || ny >= m || vis[nx][ny]) continue;
            if (a[nx][ny] == 'X') nsq.push({ nx,ny });
            else sq.push({ nx,ny });
            vis[nx][ny] = true;
        }
    }
    sq = nsq;
    return false;
}
 
void melt() {
    int sz = q.size();
    while (sz--) {
        auto cur = q.front(); q.pop();
        for (int i = 0; i < 4; ++i) {
            int nx = cur.first + dx[i];
            int ny = cur.second + dy[i];
            if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
            if (a[nx][ny] == 'X') {
                a[nx][ny] = '.';
                q.push({ nx,ny });
            }
        }
    }
}
 
int main() {
    ios::sync_with_stdio(false); cin.tie(0);
 
    cin >> n >> m;
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < m; ++j) {
            cin >> a[i][j];
            if (a[i][j] == 'L') swan.push_back({ i,j });
            if (a[i][j] == 'L' || a[i][j] == '.') q.push({ i,j });
        }
 
    sq.push({ swan[0].first,swan[0].second });
    vis[swan[0].first][swan[0].second] = true;
 
    while (1) {
        if (bfs()) break;    
        melt();
        ++ans;
    }
 
    cout << ans << endl;
 
    return 0;
}
Colored by Color Scripter
cs

 

구현할 때 조심할 점은 백조가 있는 구간도 물이라는 점이다. 따라서 55번 줄에서 백조가 있는 부분도 

물 Q에 포함시켜줘야 하고 반복문 61 ~ 64번 부분은

백조에 대해서 BFS를 해주고 만났다면 종료, 만나지 않았다면 물에 대해서 빙산을 녹이는 작업을 해주면 된다.

 

내가 작성한 코드는 950ms로 매우 간당간당한데 다른 사람의 코드와 딱히 다른 로직이 없는데도 시간 차이가

많이 나는 부분은 좀 의아하다

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

BOJ 6087 레이저 통신  (0) 2020.12.02
BOJ 14442 벽 부수고 이동하기 2  (0) 2020.12.02
BOJ 1517 버블 소트  (0) 2020.11.26
BOJ 1005 ACM Craft  (0) 2020.11.25
BOJ 3055 탈출  (0) 2020.11.24
'알고리즘/BOJ' 카테고리의 다른 글
  • BOJ 6087 레이저 통신
  • BOJ 14442 벽 부수고 이동하기 2
  • BOJ 1517 버블 소트
  • BOJ 1005 ACM Craft
khyu2
khyu2
  • khyu2
    dev log
    khyu2
  • 전체
    오늘
    어제
    • 분류 전체보기
      • 알고리즘
        • BOJ
        • Programmers
        • Algorithm
        • SWEA
      • 개발
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    행렬 제곱
    프로그래머스
    알고리즘
    우선순위 큐
    피사노 주기
    팰린드롬
    이분탐색
    큐
    조합
    다익스트라
    시뮬레이션
    이분 탐색
    BOJ
    코딩테스트 연습
    트리
    냅색
    GREEDY
    소수
    유니온 파인드
    완전 탐색
    dfs
    피보나치 수
    크루스칼
    BFS
    dp
    SWEA
    완전탐색
    MST
    구현
    분할 정복
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.3
khyu2
BOJ 3197 백조의 호수
상단으로

티스토리툴바