문제 정보
- 문제: https://www.acmicpc.net/problem/16496
- 요약: 음이 아닌 정수 N개를 배열하여 만들 수 있는 가장 큰 수를 구합니다. 수는 공백으로 구분되고, 1,000,000,000 이하의 음이 아닌 정수입니다. 0을 제외한 나머지 수는 0으로 시작하지 않습니다.
- 제한: N ≤ 1,000, 각 수 ≤ 1,000,000,000, 시간 2초, 메모리 512MB
입출력 형식/예제
| |
| |
접근 개요(아이디어 스케치)
- 핵심 관찰: 두 수
a와b를 배열할 때,a+b와b+a를 비교하여 더 큰 쪽을 앞에 배치합니다. 예를 들어 “3"과 “30"의 경우 “330” > “303"이므로 “3"을 앞에 배치합니다. - 그리디 선택: 이 비교 함수로 모든 수를 정렬하고, 앞에서부터 순서대로 이어붙입니다.
- 엣지 케이스: 모든 수가 0이면 “0"을 출력하고, 그렇지 않으면 결과 그대로 출력합니다.
- 시간 복잡도: 정렬 O(N log N × L), 여기서 L은 문자열 비교 비용입니다.
알고리즘 설계
- 비교 함수:
compare(a, b) = (a + b > b + a). 이 함수는 전이적(transitive) 성질을 만족합니다. - 정렬:
sort함수에 커스텀 비교자를 적용하여 문자열 벡터를 정렬합니다. - 연결: 정렬된 문자열들을 순서대로 이어붙여 결과 문자열을 생성합니다.
- 0 처리: 결과 문자열의 첫 문자가 ‘0’이면 “0"만 출력합니다.
올바름 근거(요지)
- 비교 함수의 전이성:
compare(a, b)가 true이고compare(b, c)가 true이면,compare(a, c)도 true입니다. 이는 수학적으로 증명 가능하며, 정렬의 정확성을 보장합니다. - 그리디 선택 성질: 각 위치에서 국소적으로 최적의 선택(가장 큰 연결 결과를 만드는 배치)이 전역 최적해를 도출합니다.
- 정당성: 어떤 두 인접한 수의 배치 순서를 바꾸면 결과가 더 작아지므로, 정렬된 배열의 순서대로 이어붙인 결과가 최대값입니다.
복잡도
- 시간: O(N log N × L), 여기서 N은 수의 개수, L은 평균 문자열 길이입니다.
- 공간: O(N × L), 문자열 벡터 저장 공간
구현 (C++)
| |
코드 설명
헤더 및 입력:
#include <bits/stdc++.h>로 표준 라이브러리 포함- Fast I/O 설정으로 입출력 속도 향상
n과n개의 숫자를 문자열 배열에 저장
비교 함수:
a + b와b + a를 문자열 연결로 비교합니다.- 결과가 더 크면
a를 앞에 배치합니다.
정렬:
sort함수와 커스텀 비교자compare를 사용하여 정렬합니다.
결과 생성:
- 정렬된 순서대로 모든 문자열을 이어붙입니다.
엣지 케이스 처리:
- 결과 문자열의 첫 문자가 ‘0’이면 (모든 숫자가 0인 경우), “0"만 출력합니다.
코너 케이스 체크리스트
- 모든 입력이 0인 경우 (예: 0, 0, 0) → “0” 출력되는지 확인
- 한 자리 숫자만 있는 경우 (예: 3, 5, 9) → 내림차순 정렬되는지 확인
- 자릿수가 다른 수들의 배치 (예: 3, 30) → 커스텀 비교 적용 확인
- 1개의 수만 있는 경우 → 그 수 그대로 출력
- 0과 양수가 섞인 경우 (예: 0, 0, 1) → “10000” 출력 확인
- 큰 숫자들 (최대 1,000,000,000) → 오버플로 없음 확인
제출 전 점검
- Fast I/O 설정 (ios::sync_with_stdio, cin.tie) 확인
- 비교 함수에서 문자열 연결 연산 정확성 확인
- 0 처리 로직이 첫 문자만 확인하는지 검증 (모든 0인 경우만 “0”)
- 개행 문자 처리 확인
참고자료/유사문제
- 문제: https://www.acmicpc.net/problem/16496
- 유사 알고리즘: 그리디 알고리즘, 커스텀 정렬, 문자열 처리
- 관련 문제: Largest Number (LeetCode 179)
코너 케이스 및 실수 포인트
| 케이스 | 설명 | 처리 방법 |
|---|---|---|
| 최소 입력 | N=1 또는 빈 입력 | 반복문 범위·예외 처리 확인 |
| 오버플로우 | 답이 $2^{31}$ 초과 가능 | long long (C++) 등 사용 |
![Featured image of post [Algorithm] C++ 백준 16496번: 큰 수 만들기](/post/algorithm/2025-12-02-boj-16496-largest-number-greedy-sorting-cpp-solution/wordcloud_hu_7ecc6c2fd1acef6c.webp)
![[Algorithm] C++ 백준 14504번: 수열과 쿼리 18](/post/algorithm/2025-12-02-boj-14504-sequence-query-18-segtree-cpp-solution/wordcloud_hu_3f06a6ae33bc42ba.webp)
![[Algorithm] C++ 백준 15782번: Calculate! 2](/post/algorithm/2025-12-02-boj-15782-calculate-2-tree-segtree-lazy-cpp-solution/wordcloud_hu_e90101ea3a15a18d.webp)
![[Algorithm] C++ 백준 16496번: 큰 수 만들기](/post/algorithm/2025-12-02-boj-16496-largest-number-greedy-sorting-cpp-solution/wordcloud_hu_467228fe986bf7a.webp)
![[Algorithm] C++ 백준 1725번: 히스토그램](/post/algorithm/2025-12-02-boj-1725-histogram-maxarea-stack-cpp-solution/wordcloud_hu_dce8145017192ecf.webp)
![[Algorithm] C++ 백준 2626번: 헬기착륙장](/post/algorithm/2025-12-02-boj-2626-helicopter-landing-site-minenc-cpp-solution/wordcloud_hu_300eea2731f29696.webp)
![[Algorithm] C++ 백준 13013번: 접미사 배열 2](/post/algorithm/2026-02-05-boj-13013-suffix-array-2-min-distinct-characters-cpp-solution/wordcloud_hu_ee21aed3564c55d3.webp)
![[Algorithm] C++ 백준 13324번: BOJ 수열 2](/post/algorithm/2025-12-19-boj-13324-boj-sequence-2-cpp-solution/wordcloud_hu_114e55a429b1c456.webp)
![[Algorithm] C++ 백준 13576번: Prefix와 Suffix](/post/algorithm/2025-08-14-boj-13576-prefix-and-suffix-cpp-solution/wordcloud_hu_cd3f9a73540c7778.webp)
![[Algorithm] C++ 백준 6223번: Cow Sorting](/post/algorithm/2025-12-19-boj-6223-cow-sorting-cpp-solution/wordcloud_hu_84bc4f73cf1f7d.webp)
![[Algorithm] C++ 백준 8155번: Postering](/post/algorithm/2025-12-19-boj-8155-postering-monotonic-stack-cpp-solution/wordcloud_hu_c7f99b415849b895.webp)