알고리즘/백준

백준 2636 치즈 c++ [컴공과고씨]

시간빌게이츠 2022. 3. 21. 14:05
반응형

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

 

2636번: 치즈

아래 <그림 1>과 같이 정사각형 칸들로 이루어진 사각형 모양의 판이 있고, 그 위에 얇은 치즈(회색으로 표시된 부분)가 놓여 있다. 판의 가장자리(<그림 1>에서 네모 칸에 X친 부분)에는 치즈가 놓

www.acmicpc.net

이 문제는 탐색 문제지만 고려해야할 것이 있다. 첫번째는 무조건 적인 탐색이 아니라 외부쪽에 있는 치즈를 전부다 방문하면 카운트 그 다음 안쪽에 있는 치즈 전부 탐색 후 카운트 이런식으로 순차적으로 가면서 카운팅을 해주어야 된다. 

그래서 나는 bfs안에 기본적인 구조가 큐를 한번 쓰는 거라면 큐를 2번을 사용하여 구현을 해주었다. 

일단 (0,0)에서 시작을 해서 탐색을 시작하여 1을 만났을 때는 temp큐에 넣어주고 0일 경우 q에 넣어 탐색을 계속해서 진행해준다. 이렇게 반복하면 가장자리의 치즈는 temp 큐에 모이게 된다. 그리고 카운트를 올려주고 temp큐에 있는 것을 q에 다시 넣어준다. 이렇게 되면 1에 있는 치즈에서 탐색을 진행하고 다음 가장자리 치즈는 temp 큐에 모이고 이것을 반복해 주는 것이다. 이렇게 하다보면 temp 큐가 비어있게 되고 temp큐가 비면 q가 비게되어서 반복문이 끝나게 된다.

그리고 q반복문을 시작할 때 q의 사이즈를 저장해두면 치즈가 다 없어지기 직전의 치즈의 개수를 알 수 있다.

 

전체코드

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
#include <iostream>
#include <queue>
using namespace std;
int r, c;
int map[101][101];
bool visit[101][101];
int dx[] = {00-11};
int dy[] = {1-100};
int cnt, area;
void bfs(){
    queue<pair<intint>> q;
    queue<pair<intint>> temp;
    q.push(make_pair(00));
    while(!q.empty()){
        area = q.size(); // 남은 치즈 개수 체크
        while(!q.empty()){
            int x = q.front().first;
            int y = q.front().second;
            q.pop();
            for (int i = 0; i < 4;i++){
                int nx = x + dx[i];
                int ny = y + dy[i];
 
                if (nx >= 0 && nx < c && ny >=0 && ny <r){
                    if(!visit[ny][nx] && map[ny][nx] == 1){
                        temp.push(make_pair(nx, ny)); // 가장자리 치즈 만 저장
                    }else if(!visit[ny][nx] && map[ny][nx] == 0){
                        q.push(make_pair(nx, ny)); //탐색 진행
                    }
                    visit[ny][nx] = true;
                }
            }
        }
        while(!temp.empty()){
            q.push(temp.front());
            temp.pop();
        }
        cnt++;
    }   
}
int main(){
    cin >> r >> c;
    for (int i = 0; i < r;i++){
        for (int j = 0; j < c;j++){
            cin >> map[i][j];
        }
    }
    visit[0][0= true;
    bfs();
    cout << cnt-1 << '\n'// while문 구조상 카운트가 한번 더 됨.
    cout << area << '\n';
    return 0;
}
cs

사용 문법 : bfs

반응형