2016년 3월 11일 금요일

1024 - 수열의 합

https://www.acmicpc.net/problem/1024

합이 N이고 길이가 L이 되게 만드는 수는 단순히 생각한다면 (N/L) * L 일것이다.
이 말은, N/L 의 양쪽으로 L 만큼의 범위내에서 정답이 존재한다는 것이다.
18을 예로 들면, L=2 일때는 [8 9] 혹은 [9 10] 중에 답이 있고, L=3 일때는 [3 4 5] ~ [6 7 8] 중에 있다는 것이다. (L=3 이면 답은 5+6+7)

이런 아이디어에서 출발해서 L을 점점 늘려가면서 정답을 찾았다.
구간을 설정하고 그 시작점이 원하는 답 N을 넘어가면 그 이상의 수는 더 살펴볼 필요가 없다. (왜냐면 그 수 이후로는 합쳐서 N이 나올수가 없다. 무조건 N 을 넘는다)

L=2 부터 L=100 까지 답을 찾고, 없으면 -1 을 출력했다.
#include <cstdio>

typedef long long int lld;

inline lld max(lld a, lld b){return a>b?a:b;}

int main(){
    lld i, j, k, N, L;
    scanf("%lld %lld", &N, &L);
    for(int l=L; l<=100; ++l){
        for(lld n=N/l-l; n <= N; ++n){
            lld m = n-l+1;
            if(m < 0) continue;
            lld r = n*(n+1)/2 - m*(m-1)/2;
            // printf("%lld ~ %lld = %lld\n", m, n, r);
            if(r > N) break;
            if(r == N){
                for(lld k=m; k<=n; ++k) printf("%lld ", k);
                return 0;
            }
        }
    }
    puts("-1");
    return 0;
}

댓글 없음:

게시글 목록