seukseok의 개인 블로그

BOJ 풀이 노트: DFS 경로 탐색과 투 포인터 감각 복습

· tech

오늘은 BOJ 13023과 3273을 묶어, 방문 처리 백트래킹이 핵심인 DFS와 중복 없이 쌍을 세는 투 포인터 구현 포인트를 실수 방지 중심으로 정리했다.

오늘은 그래프 탐색 1문제 + 정렬/투 포인터 1문제로 조합했다.

하나는 “깊이 조건을 만족하는 경로 존재 여부”를 묻는 문제고, 다른 하나는 “합이 특정 값이 되는 쌍의 개수”를 세는 문제라 사고 방식이 확실히 다르다. 하루 2문제 루틴에서 기본기 점검용으로 균형이 좋았다.

1) BOJ 13023 - ABCDE

문제 핵심 요약

사람 관계 그래프(무방향)에서 서로 다른 5명 A-B-C-D-E가 연속 친구 관계를 이루는 경로가 존재하는지 판단하는 문제다. 존재하면 1, 아니면 0을 출력한다.

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

요구사항은 최단거리/개수 계산이 아니라 길이 4(정점 5개) 단순 경로 존재 여부다. 그래서 각 정점을 시작점으로 DFS를 돌리면서 깊이가 5가 되는 순간 즉시 성공 처리하면 된다.

핵심은 방문 배열을 재귀 진입/복귀 시점에 정확히 되돌리는 백트래킹이다.

이 패턴이 깨지면 다른 분기 탐색이 막혀 오답이 난다.

시간/공간 복잡도

실수하기 쉬운 포인트

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

if (depth == 5) {
    found = true;
    return;
}

정점 5개 연속 경로를 찾는 즉시 종료 플래그를 세운다.

visited[nxt] = true;
dfs(nxt, depth + 1);
visited[nxt] = false;

백트래킹의 핵심. 분기 탐색 독립성을 보장한다.

다른 풀이 가능성


2) BOJ 3273 - 두 수의 합

문제 핵심 요약

서로 다른 두 수를 골라 합이 x가 되는 쌍의 개수를 구하는 문제다.

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

정렬 후 양끝 포인터를 두면 한 번의 선형 스캔으로 해결된다.

정렬 덕분에 포인터 이동 방향의 근거가 명확해서 O(N^2) 완전탐색을 O(N log N)으로 줄일 수 있다.

시간/공간 복잡도

실수하기 쉬운 포인트

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

while (left < right) {
    int sum = a[left] + a[right];

반드시 서로 다른 두 원소만 보도록 루프 조건을 건다.

if (sum == x) {
    answer++;
    left++;
    right--;
}

정답을 찾았을 때 양쪽을 함께 이동해 같은 쌍을 다시 세지 않도록 한다.

다른 풀이 가능성


오늘 정리 포인트:

내일도 서로 다른 유형 2문제를 섞어 기본기 루틴을 이어가겠다.