[백준] 단지번호붙이기 2667 (silver 1) - c++

2026. 2. 1. 21:03·Algorithms/Problem Solving

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

 

이 문제는
2차원 격자에서 연결된 컴포넌트(Connected Component)를 찾는 전형적인 문제다.

겉으로 보면 단순한 BFS 문제처럼 보이지만,
막상 구현하려고 하면 다음 지점에서 많이 막히게 된다.

  • BFS를 어떻게 여러 번 호출하지?
  • 각 단지가 몇 개의 집으로 이루어졌는지는 어디서 세야 하지?

나 역시 이 아이디어를 떠올리는 데 꽤 시간이 걸렸다.


문제 핵심 요약

  • 1 → 집이 있는 곳
  • 0 → 집이 없는 곳
  • 상하좌우로 연결된 1들의 묶음이 하나의 단지
  • 구해야 할 것
    1. 전체 단지 개수
    2. 각 단지에 포함된 집의 수 (오름차순 출력)

즉, 이 문제는
👉 “BFS 한 번 = 단지 하나” 라는 관점으로 접근해야 한다.


접근하면서 가장 어려웠던 점

처음에는 이런 생각까지는 하고 있었다.

  • 단지 개수는 vector에 담아서 result.size()로 세면 되겠지
  • 각 단지의 크기도 어딘가에 저장해야 한다

문제는 그걸 어디서 계산해야 하는지였다.

  • BFS는 한 번만 도는 건가?
  • 아니면 단지마다 BFS를 다시 호출해야 하나?
  • BFS 함수 안에서는 뭘 계산하고, 밖에서는 뭘 해야 하지?

이 구조가 명확하지 않아서 계속 헷갈렸다.


핵심 아이디어

이 문제의 핵심 아이디어는 딱 하나다.

아직 방문하지 않은 집(1)을 발견할 때마다 BFS를 새로 시작한다

그리고 그 BFS는

  • 하나의 단지만 탐색
  • 그 단지에 포함된 집의 개수를 세서 반환

이렇게 역할을 나누는 것이다.


전체 탐색 구조

for(int i = 0; i < n; i++){
    for(int j = 0; j < n; j++){
        if(visited[i][j] || maps[i][j] == 0) continue;
        result.push_back(bfs(i, j));
    }
}
  • 아직 방문하지 않은 1을 만나면
  • bfs(i, j) 호출
  • 반환값 = 해당 단지의 크기
  • 이를 result에 저장

👉 BFS 호출 횟수 = 단지 개수


BFS 함수의 역할

BFS 함수는 한 단지에 대해서만 책임진다.

int bfs(int a, int b){
    queue<pair<int,int>> q;
    q.push({a,b});
    visited[a][b] = 1;

    int cnt = 0;

    while(!q.empty()){
        auto cur = q.front();
        q.pop();
        cnt++;

        for(int i = 0; i < 4; i++){
            int ny = cur.first + dy[i];
            int nx = cur.second + dx[i];

            if(ny < 0 || nx < 0 || ny >= maps.size() || nx >= maps.size())
                continue;
            if(visited[ny][nx] || maps[ny][nx] == 0)
                continue;

            visited[ny][nx] = 1;
            q.push({ny, nx});
        }
    }
    return cnt;
}
  • 큐에서 하나 꺼낼 때마다 cnt++
  • BFS가 끝나면
    • 그 단지의 집 개수 = cnt
  • 이 값을 호출한 쪽에서 그대로 사용

왜 이런 구조여야 하는가?

이 구조를 쓰면 역할이 명확해진다.

  • main 함수
    • 전체 격자 순회
    • BFS를 언제 시작할지 결정
    • 단지 개수 관리
  • BFS 함수
    • 단지 하나 탐색
    • 해당 단지 크기 계산

그래서

  • 단지 개수 → result.size()
  • 단지별 크기 → result 내부 값

으로 자연스럽게 이어진다.


최종 출력

cout << result.size() << '\n';
sort(result.begin(), result.end());
for(int a : result){
    cout << a << '\n';
}

정리

  • BOJ 2667은 BFS를 한 번만 쓰는 문제가 아니다
  • BFS를 “단지 단위”로 여러 번 호출하는 문제다
  • BFS 함수는
    • 탐색
    • 카운트
      두 역할만 맡기고
  • 전체 구조는 바깥에서 관리하는 것이 핵심이다

이 관점을 잡고 나면
단지번호붙이기뿐 아니라
연결 요소 개수 / 영역 크기 문제들이 한 번에 정리된다.

 

'Algorithms > Problem Solving' 카테고리의 다른 글

[백준] 이분 그래프 1707 (Gold 4) - C++  (0) 2026.02.09
[백준] 토마토 7576 (Gold 5) - C++  (0) 2026.02.09
[백준] DFS와 BFS 1260 (Silver 2) - C++  (0) 2026.02.01
[프로그래머스] 영어 끝말잇기 (12981) - C++  (0) 2026.01.25
[백준] 문자열 집합 14425 (Silver4) - C++ Hash 함수  (1) 2026.01.21
'Algorithms/Problem Solving' 카테고리의 다른 글
  • [백준] 이분 그래프 1707 (Gold 4) - C++
  • [백준] 토마토 7576 (Gold 5) - C++
  • [백준] DFS와 BFS 1260 (Silver 2) - C++
  • [프로그래머스] 영어 끝말잇기 (12981) - C++
wlals916
wlals916
  • wlals916
    JM.devlog
    wlals916
    GitHub
  • 전체
    오늘
    어제
    • 분류 전체보기 (28)
      • Algorithms (20)
        • Problem Solving (14)
        • Language & Concept (6)
      • Backend (7)
        • Study Notes (1)
        • Trouble Shooting (6)
        • Development (0)
      • AI (0)
      • Review (1)
      • Dev Log (0)
  • 관리자

    • 글쓰기
    • 관리 페이지
    • 티스토리 홈
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
    • 글쓰기
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    백엔드
    코딩테스트
    김영한
    SpringBoot
    DevOps
    회고
    코테
    백준
    C++
    프로그래머스
  • 최근 댓글

  • hELLO· Designed By정상우.v4.10.6
wlals916
[백준] 단지번호붙이기 2667 (silver 1) - c++
상단으로

티스토리툴바