티스토리 뷰

알고리즘/백준(BOJ)

백준 - 16236 아기 상어

시나모온 2020. 7. 12. 01:10

문제 링크입니다 : https://www.acmicpc.net/problem/16236

 

16236번: 아기 상어

N×N 크기의 공간에 물고기 M마리와 아기 상어 1마리가 있다. 공간은 1×1 크기의 정사각형 칸으로 나누어져 있다. 한 칸에는 물고기가 최대 1마리 존재한다. 아기 상어와 물고기는 모두 크기를 가��

www.acmicpc.net

BFS + 구현 문제

 

생각할게 많아서 쫌 어렵게 느껴졌다.

 

 

 

#include <iostream>
#include <vector>
#include <queue>

using namespace std;

const int dy[4] = {-1, 0, 0, 1};
const int dx[4] = {0, -1, 1, 0};

int fishCnt[7];
int N;
vector<vector<int>> board;
vector<vector<bool>> visited;

inline int countEdible(int size) {
    int cnt = 0;
    int min = size < 7 ? size : 7;
    for(int i = 1; i < min; i++) {
        cnt += fishCnt[i];
    }
    return cnt;
}

int BFS(int y, int x) {
    // eatCount, cury, curx
    queue<pair<int, pair<int, int>>> q;
    q.push({0, {y, x}});
    visited[y][x] = true;
    int step = 0;
    int size = 2;
    int ret = 0;

    priority_queue<pair<pair<int, int>, int>> pq;


    while(!q.empty()) {
        int qSize = q.size();
        bool flag = false;
        for(int i = 0; i < qSize; i++) {
            int ceat = q.front().first;
            int cy = q.front().second.first;
            int cx = q.front().second.second;
            q.pop();

            if(countEdible(size) == 0) return step;

            for(int dir = 0; dir < 4; dir++) {
                int ny = cy + dy[dir];
                int nx = cx + dx[dir];
                if(ny < 0 || ny >= N || nx < 0 || nx >= N) continue;
                if(board[ny][nx] > size) continue;
                if(visited[ny][nx]) continue;
                visited[ny][nx] = true;
                if(board[ny][nx] >= 1 && board[ny][nx] < size) {
                    flag = true;
                    pq.push({{-ny, -nx}, ceat + 1});
                }
                q.push({ceat, {ny, nx}});
            }
        }

        if(flag) {
            while(!q.empty()) {
                q.pop();
            }

            int ny = -pq.top().first.first;
            int nx = -pq.top().first.second;
            int ceat = pq.top().second % size; 
            q.push({ceat, {ny, nx}});
            size += pq.top().second / size;
            ret = step + 1;
            fishCnt[board[ny][nx]]--;
            board[ny][nx] = 0;
            visited.assign(N, vector<bool>(N, false));
            visited[ny][nx] = true;
            
            while(!pq.empty()) {
                pq.pop();
            }
        }

        step++;
    }
    return ret;
}

int main() {
    cin >> N;
    board.assign(N, vector<int>(N, 0));
    visited.assign(N, vector<bool>(N, false));
    int starty, startx;
    for(int i = 0; i < N; i++) {
        for(int j = 0; j < N; j++) {
            cin >> board[i][j];
            if(board[i][j] >= 1 && board[i][j] <= 6) fishCnt[board[i][j]]++;
            else if(board[i][j] == 9) {
                board[i][j] = 0;
                starty = i;
                startx = j;
            }
        }
    }

    cout << BFS(starty, startx);

    return 0;
}

 

 

 

개발 환경 : vscode

지적, 조언, 질문 환영입니다! 댓글 남겨주세요~

 

'알고리즘 > 백준(BOJ)' 카테고리의 다른 글

백준 - 19236 청소년 상어  (0) 2020.07.12
백준 - 17086 아기 상어 2  (0) 2020.07.12
백준 - 2887 행성 터널  (0) 2020.07.11
백준 - 1774 우주신과의 교감  (1) 2020.07.10
백준 - 4386 별자리 만들기  (0) 2020.07.10
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
«   2025/04   »
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
글 보관함