-
[99클럽/코딩테스트 챌린지/C++] 징검다리 문제에서 이분 탐색으로 최대 징검다리 수 찾기2024년 10월 29일
- 유니얼
-
작성자
-
2024.10.29.:17
728x90오늘은 징검다리 문제에서 이분 탐색을 활용하여 최대 몇 개의 징검다리를 밟을 수 있는지 찾는 풀이 방법을 정리했습니다. 이 문제에서 중요한 부분은 조건을 수식으로 변환하고, 오버플로우를 방지하는 이분 탐색을 사용하는 것이었습니다.
문제링크 :
https://www.acmicpc.net/problem/11561
문제 접근 과정
- 규칙 분석
- 승택이는 N번 징검다리를 반드시 밟아야 하며, 이전에 밟았던 징검다리보다 1 이상 더 먼 거리를 점프해야 합니다. 예를 들어, 점프 거리가 1, 2, 3, ..., K가 되며, 이 점프들의 총합이 N을 넘지 않아야 합니다.
- 이 규칙을 통해 등차수열의 합 공식을 적용할 수 있습니다: 합 = K * (K + 1) / 2
- K 값 찾기 - 이분 탐색을 활용한 최대값 찾기
- 이분 탐색을 통해 조건을 만족하는 최대 K를 찾습니다.
- 각 K에 대해 점프 거리의 합인 K * (K + 1) / 2가 N보다 작거나 같은지 확인합니다.
- 이때, 중간 값 mid를 K로 설정하고, 조건을 만족하면 K를 더 크게, 만족하지 않으면 더 작게 조정합니다.
코드 풀이
아래는 문제 해결을 위한 최종 코드입니다:
#include <iostream> using namespace std; long long maxStone(long long n) { long long left = 1, right = 1000000000; long long result = 1; while (left <= right) { long long mid = (left + right) / 2; // 오버플로우 방지: mid * (mid + 1) / 2 <= n 대신 (2 * n) >= mid * (mid + 1) 형태로 비교 if (mid <= (2 * n) / (mid + 1)) { result = mid; // 가능한 최대 K 저장 left = mid + 1; // 더 큰 K를 시도 } else { right = mid - 1; // 더 작은 K를 시도 } } return result; } int main() { int t; cin >> t; while (t-- > 0) { long long n; cin >> n; cout << maxStone(n) << endl; } return 0; }
배운 점
이 문제를 통해 이분 탐색과 오버플로우 방지 방법을 배울 수 있었습니다.
- 이분 탐색의 활용 : 문제에서 특정 조건을 만족하는 최대값을 찾을 때 이분 탐색이 매우 유용하다는 점을 다시 확인했습니다. 큰 입력을 효율적으로 탐색할 수 있어 시간이 제한된 문제에서도 안정적입니다.
- 단순한 조건일수록 효율적인 수식화 : 문제 조건을 수식으로 단순화하는 과정이 문제 해결의 핵심이었습니다. 등차수열의 합 공식이 문제에 잘 적용되었고, 이를 통해 문제 조건을 명확히 정의할 수 있었습니다.
결론
이 문제를 통해 이분 탐색을 통한 최적의 값 찾기와 수식 변형을 통한 오버플로우 방지라는 두 가지 중요한 기법을 익혔습니다. 앞으로는 문제에서 조건을 더 단순한 수식으로 표현하고, 이분 탐색을 유연하게 활용할 수 있도록 노력해야겠다고 느꼈습니다.
반응형다음글이전글이전 글이 없습니다.댓글
스킨 업데이트 안내
현재 이용하고 계신 스킨의 버전보다 더 높은 최신 버전이 감지 되었습니다. 최신버전 스킨 파일을 다운로드
받을 수 있는 페이지로 이동하시겠습니까?
("아니오" 를 선택할 시 30일 동안 최신 버전이
감지되어도 모달 창이 표시되지 않습니다.)