본문 바로가기
Algorithm

[백준 16000] 섬

by YEON-DU 2020. 8. 8.
반응형

https://www.acmicpc.net/problem/16000

 

16000번: 섬

N 개의 줄에 길이 M 의 문자열을 출력하라. 이 중 i 번째 줄의 j 번째 문자는 (i, j) 셀의 상태를 나타내어야 한다. 만약 (i, j) 셀이 바다라면 해당 위치에 '.'을 출력해야 하고, 안전한 섬의 일부

www.acmicpc.net

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

#define fastio() ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);

// 섬
// 모든 가장자리는 바다이다
// 4방향 bfs 탐색으로 이어져있는 섬은 한 섬이다.

typedef pair<int, int> point;
int N, M;
string input[2001];
vector <char> answer;
int index_map[2001][2001];
point dir[4] = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};
point diagonal[4] = {{1, 1}, {-1, 1}, {-1, -1}, {1, -1}};

void bfs(int r, int c, int idx) {
    
    queue <point> que;
    que.push({r, c});
    index_map[r][c] = idx;
    
    while(!que.empty()) {
        point p = que.front();
        que.pop();
        
        for(int i = 0; i<4; i++) {
            int rr = p.first + dir[i].first;
            int cc = p.second + dir[i].second;
            
            if(rr < 0 || rr >= N || cc < 0 || cc >= M) continue;
            if(index_map[rr][cc] != 0) continue;
            if(input[rr][cc] == '.') continue;
            
            index_map[rr][cc] = idx;
            que.push({rr, cc});
        }
    }
}

int indexing() {
    int count = 0;
    for(int i = 0; i<N; i++)
        for(int j = 0; j<M; j++)
            if(input[i][j] == '#' && index_map[i][j] == 0) {
                bfs(i, j, count + 1);
                count++;
            }
    
    return count;
}

void checkSafety(int r, int c) {
    
    index_map[r][c] = -1;
    queue <point> que;
    que.push({r, c});
    
    while(!que.empty()) {
        point p = que.front();
        que.pop();
        
        for(int i = 0; i<4; i++) {
            int rr = p.first + dir[i].first;
            int cc = p.second + dir[i].second;
            
            if(rr < 0 || rr >= N || cc < 0 || cc >= M) continue;
            
            if(index_map[rr][cc] > 0) {
                answer[index_map[rr][cc] - 1] = 'O';
                continue;
            }
            
            if(index_map[rr][cc] == 0 && input[rr][cc] == '.') {
                index_map[rr][cc] = -1;
                que.push({rr, cc});
            }
        }
        
        for(int i = 0; i<4; i++) {
            // 대각선 영역
            int rr = p.first + diagonal[i].first;
            int cc = p.second + diagonal[i].second;
      
            if(rr < 0 || rr >= N || cc < 0 || cc >= M) continue;
            if(input[rr][cc] == '#') continue;
            
            // 대각선에 바다가 있을 때
            // 엇갈려있는 섬이 서로 다른 섬이라면
            if(index_map[rr][cc] != -1 && index_map[rr][p.second] > 0
               && index_map[p.first][cc] > 0 && index_map[rr][p.second] != index_map[p.first][cc]) {
                index_map[rr][cc] = -1;
                que.push({rr, cc});
            }
        }
    }
    
}


int main() {
    
    fastio();
    
    cin >> N >> M;
    
    for(int i = 0; i<N; i++)
        cin >> input[i];
    
    int island = indexing();
    answer.resize(island, 'X');
    
    checkSafety(0, 0);
    for(int i = 0; i<N; i++) {
        for(int j = 0; j<M; j++)
        {
            if(input[i][j] == '.') cout << '.';
            else cout << answer[index_map[i][j] - 1];
        }
        cout << '\n';
    }
    
    return 0;
}

반응형

'Algorithm' 카테고리의 다른 글

[백준 17144] 미세먼지 안녕!  (0) 2020.08.24
[백준 14503] 로봇 청소기  (0) 2020.08.23
[백준 19236] 청소년 상어  (0) 2020.07.30
[백준 12025] 장난꾸러기 영훈  (0) 2020.07.26
[백준 18809] Gaaaaaaaaaarden  (0) 2020.07.05

댓글