← Back to Blog

[백준 1024번 | C++] 수열의 합

computer-science > problem-solving

2026-03-042 min read

#development #cs #problem-solving #brute-force #cpp #math

출처: 수열의 합

시간 제한메모리 제한
2 초128 MB

문제

N과 L이 주어질 때, 합이 N이면서, 길이가 적어도 L인 가장 짧은 연속된 음이 아닌 정수 리스트를 구하는 프로그램을 작성하시오.

입력

첫째 줄에 N과 L이 주어진다. N은 1,000,000,000보다 작거나 같은 자연수이고, L은 2보다 크거나 같고, 100보다 작거나 같은 자연수이다.

출력

만약 리스트의 길이가 100보다 작거나 같으면, 연속된 수를 첫째 줄에 공백으로 구분하여 출력한다. 만약 길이가 100보다 크거나 그러한 수열이 없을 때는 -1을 출력한다.


풀이

길이가 적어도 LL 인 연속된 음이 아닌 정수 리스트를 구해야 한다.
연속된 음이 아닌 정수 리스트가 조건이기 때문에 다음과 같이 수식을 만들어볼 수 있다.

N=start point+end point2×list lengthN = \frac{\text{start point} + \text{end point}}{2} \times \text{list length}

여기서
start point\text{start point}aa 로,
list length\text{list length}kk 라 설정하겠다.

end point\text{end point}a+k1a + k - 1 이 된다.
시작점에서 수열 길이 만큼 뒤에 있으니 말이다.

그러면 다음과 같이 수식을 전개할 수 있다.

N=k×a+(a+k1)2=k×2a+k12=ka+k(k1)2a=Nk(k1)2k\begin{align} N &= k \times \frac{a + (a+k-1)}{2}\\ &= k \times \frac{2a + k - 1}{2}\\ &= ka + \frac{k(k - 1)}{2}\\ a &= \frac{N - \frac{k(k - 1)}{2}}{k} \end{align}

시작점, 즉 aa"음이 아닌 정수" 이기 때문에,

(Nk(k1)2)modk=0\left(N - \frac{k(k-1)}{2}\right) \operatorname{mod} k = 0

이여야 한다.

이 조건을 만족하지 않는다면 두 가지 경우다.

  1. 수열의 길이가 kk 보다 크다.
  2. 만족하는 수열이 없다.

코드

// 1024
#include <iostream>
using namespace std;

int N; // <= 1'000'000'000
int L;

int main() {
    cin >> N >> L;
    for (int k = L; k <= 100; ++k) {
        int tmp = N - k*(k-1)/2;
        if (tmp < 0)
            continue;

        if (tmp % k == 0) {
            int start = tmp / k;
            for (int i = 0; i < k; ++i) {
                cout << start + i<< ' ';
            }
            return 0;
        }
    }
    cout << -1;

    return 0;
}