
자연수 개의 합이 가 되면서, 그 원소들의 곱이 최대가 되는 집합을 구하는 문제다. 핵심은 "곱이 최대가 되려면 수들이 최대한 균등해야 한다"는 수학적 직관이다. 이를 이용해 몫과 나머지를 계산하여 에 해결했다.
s/n) 맞춘 뒤, 뒤쪽 원소부터 하나씩 값을 늘려가는 방식을 생각했다.vector에 값을 채워 넣는 과정(push_back)에서 뒤쪽부터 접근하려면 인덱스 처리가 번거롭다는 것을 깨달았다.{-1} 반환.s/n)을 가져야 한다.s%n)만큼을 개의 원소 중 일부에게 +1씩 더해줘야 한다.몫)를 먼저 채우고, 큰 수(몫+1)를 나중에 채우면 sort 함수를 쓸 필요가 없다.#include <string>
#include <vector>
using namespace std;
vector<int> solution(int n, int s) {
vector<int> answer;
// 불가능한 경우 처리 (자연수의 합 최소 조건)
if (s < n) {
answer.push_back(-1);
return answer;
}
int quotient = s / n; // 기본적으로 가져갈 값
int remainder = s % n; // +1을 해줘야 하는 원소의 개수
// 핵심 로직: 오름차순을 위해 작은 수부터 채운다.
// 전체 n개 중 (n - remainder)개는 몫을 그대로 가짐
// 나머지 remainder개는 몫에 +1을 한 값을 가짐
for (int i = 0; i < n; ++i) {
if (i < n - remainder) {
answer.push_back(quotient);
} else {
answer.push_back(quotient + 1);
}
}
return answer;
}
s/n으로 다 채우고 나서 루프를 돌며 값을 수정하려 했다.sort 비용도 아꼈다.| 항목 | 내용 |
|---|---|
| 유형 | 수학 (Mathematics), 구현 |
| 체감 난이도 | 하 (수학적 원리만 알면 매우 쉬움) |
| 복잡도 | 시간: , 공간: |
| 새로 배운 것 | 합이 일정할 때 곱을 최대로 만드는 법(편차 줄이기), 정렬 비용을 아끼는 채우기 전략 |