seukseok의 개인 블로그

BOJ 풀이 노트: 이분 탐색과 다익스트라 기본기 점검

· tech

BOJ 1654, 1916을 문제 핵심 요약, 접근 아이디어, 복잡도, 실수 포인트, 핵심 코드 설명과 대안 풀이까지 실전 관점으로 정리한 글.

오늘은 서로 결이 다른 두 문제를 묶어서 풀었다.

하나는 정답 범위를 줄여가는 이분 탐색, 다른 하나는 최단 경로의 정석인 다익스트라다. 둘 다 실전에서 반복적으로 나오는 패턴이라 기본기 점검용으로 좋았다.

1) BOJ 1654 - 랜선 자르기

문제 핵심 요약

기존 랜선 K개를 잘라서 길이가 같은 랜선 N개 이상을 만들어야 한다. 만들 수 있는 랜선의 최대 길이를 구하는 문제다.

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

핵심은 “길이 L로 잘랐을 때 N개 이상 만들 수 있는가?”라는 판정 문제로 바꿀 수 있다는 점이다.

즉, 가능/불가능이 단조성을 가지므로 이분 탐색이 정확히 맞는다.

시간/공간 복잡도

실수하기 쉬운 포인트

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

long long mid = (lo + hi) / 2;
long long count = 0;
for (long long len : cables) {
    count += len / mid;
}
if (count >= n) {
    ans = mid;
    lo = mid + 1;
} else {
    hi = mid - 1;
}

다른 풀이 가능성

파라메트릭 서치 관점에서 동일한 이분 탐색이 사실상 표준 해법이다. 완전탐색은 길이 범위가 커서 비현실적이다.


2) BOJ 1916 - 최소비용 구하기

문제 핵심 요약

도시와 버스 정보(방향 그래프, 가중치 양수)가 주어질 때, 시작 도시에서 도착 도시까지 가는 최소 비용을 구하는 문제다.

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

간선 가중치가 음수가 없으므로 다익스트라를 적용하면 된다.

이 문제는 단일 시작점 최단 경로의 전형이라, 다익스트라 구현 정확도가 핵심이다.

시간/공간 복잡도

실수하기 쉬운 포인트

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

priority_queue<pair<long long, int>, vector<pair<long long, int>>, greater<>> pq;
if (curDist != dist[cur]) continue;
long long nd = curDist + cost;
if (nd < dist[next]) {
    dist[next] = nd;
    pq.push({nd, next});
}

다른 풀이 가능성

모든 정점 쌍 최단 경로가 필요하다면 플로이드-워셜을 고려할 수 있지만, 이 문제처럼 단일 출발/도착에서는 다익스트라가 훨씬 효율적이다.


오늘 정리 포인트:

전형 문제를 정확히 푸는 루틴을 유지하면, 응용 문제에서도 설계 속도와 안정성이 같이 올라간다.