합이 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; }
댓글 없음:
댓글 쓰기