seukseok의 개인 블로그

BOJ 풀이 노트: DSLR 상태 탐색과 그림 BFS 기본기 점검

· tech

오늘은 BOJ 9019와 1926을 묶어 상태 전이 최단 경로 BFS와 격자 연결요소 BFS를 실수 방지 관점으로 정리했다.

오늘은 BFS를 서로 다른 형태로 쓰는 2문제를 선택했다.

둘 다 BFS지만, 9019는 숫자 상태 전이를 다루는 문제이고 1926은 2차원 격자에서 연결된 영역을 세는 문제다. 구현 디테일이 달라서 같이 복습하기 좋았다.

1) BOJ 9019 - DSLR

문제 핵심 요약

정수 AB로 바꾸는 최소 연산 수열을 구한다. 가능한 연산은 D, S, L, R 네 가지이며, 정수 범위는 0~9999로 고정이다. 정답은 최소 길이의 연산 문자열이다.

접근 아이디어(왜 이 방법인지)

각 숫자(0~9999)를 그래프의 정점으로 보고, 연산 4개를 간선으로 보면 된다. 모든 간선 비용이 1이므로 BFS를 쓰면 최초 도달이 최단 경로다.

핵심은 경로 복원이다.

이렇게 하면 최소 연산 문자열을 정확히 복원할 수 있다.

시간/공간 복잡도

실수하기 쉬운 포인트

C++ 코드 설명(핵심 라인)

int l = (cur % 1000) * 10 + (cur / 1000);
int r = (cur / 10) + (cur % 10) * 1000;

네 자리 정수 회전을 산술로 처리한 부분이다. 문자열 변환 없이 상수 시간으로 다음 상태를 만든다.

prev[nx] = cur;
op[nx] = c;

최단 경로 복원을 위해 다음 상태의 직전 정점과 연산 문자를 저장한다.

다른 풀이 가능성


2) BOJ 1926 - 그림

문제 핵심 요약

01로 이루어진 n x m 격자에서, 상하좌우로 연결된 1 묶음을 그림 하나로 본다. 구해야 하는 값은:

  1. 그림의 개수
  2. 가장 넓은 그림의 넓이

접근 아이디어(왜 이 방법인지)

격자에서 연결요소를 세는 전형 문제다. 방문하지 않은 1을 시작점으로 BFS를 돌리면 해당 그림의 넓이를 구할 수 있고, 이런 시작 BFS 횟수가 곧 그림 개수다.

즉,

구조가 명확해서 실수 포인트를 줄이기 좋다.

시간/공간 복잡도

실수하기 쉬운 포인트

C++ 코드 설명(핵심 라인)

if (board[i][j] == 0 || visited[i][j]) continue;

새 BFS를 시작해야 하는 정확한 조건이다. 방문하지 않은 1에서만 시작한다.

if (nx < 0 || nx >= n || ny < 0 || ny >= m) continue;
if (visited[nx][ny] || board[nx][ny] == 0) continue;

격자 BFS의 필수 안전장치다. 범위와 방문/값 조건을 분리해 가독성과 디버깅성을 높였다.

다른 풀이 가능성


오늘 정리 포인트: