- 링크: www.acmicpc.net/problem/1024
이런 문제가 제일 어렵습니다. 단순한 것 같으면서? 막상 풀려고 하면 손이 움직이지 않습니다. 왜냐, 저는 수알못이기 때문입니다.
N과 L이 주어질 때, 합이 N이면서, 길이가 적어도 L인 가장 짧은 연속된 음이 아닌 정수 리스트를 구하는 프로그램을 작성하시오.
이떄 입력조건이 N=[1, 10억], L=[2, 100]인 점 유의하셔야 합니다. "음이 아닌 정수 리스트"를 구한다는 것도 주의를 하시고요. 즉 수가 0 이상이라는 거겠죠
N의 범위가 넓기 때문에 브루트포스나 뭐 여타 등등의 방법은 안됩니다. 결국 정공법인 수학으로 풀어야 합니다
적당히 수열의 맨 처음 수를 a 라고 하겠습니다.
(L=2) a, a+1 -> 합: 2a+1
(L=3) a, a+1, a+2 -> 합: 3a+3
(L=4) a, a+1, a+2, a+3 -> 합: 4a+6
...
(L=n) a, a+1, ... a+n -> 합: n*a + (n*(n-1))/2
그때 순열의 길이(L)에 따른 합을 쓰면 이렇게 됩니다. 결국 저 목록중에 a에다 적당한 값을 넣었을 때 합이 N이 되도록 할 수 있느냐? 이걸 찾으면 순열을 만들 수 있겠죠
처음엔 이상한 가정(L%2 != N%2)을 세우고 풀기 시작해서 헛다리를 좀 짚었습니다.
그 다음엔 for 루프 인덱스 범위에 eq가 빠져서 삽질을 약간 했습니다.
맥에서 C++ 개발환경 테스트겸 문제 아무거나 하나 쉬운거 풀어보려고 한건데, 한시간을 써버렸네요 ;
#ifdef ONLINE_JUDGE
#include <bits/stdc++.h>
#else
#include "stdc++.h"
#endif // ONLINE_JUDGE
using namespace std;
int main() {
#ifndef ONLINE_JUDGE
freopen("input.txt", "r", stdin);
#endif // ONLINE_JUDGE
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N, L;
cin >> N >> L;
for (int i=L; i<=100; ++i) {
int remainder = (i*(i-1))/2;
int unit = N-remainder;
if (unit>=0 && unit%i==0) {
int a = unit / i;
for (int j=0; j<i; ++j) {
cout << a+j;
if (j != i-1)
cout << " ";
}
return 0;
}
}
cout << "-1\n";
return 0;
}
반응형
'Online Judge > 백준' 카테고리의 다른 글
[백준][Java] 14013: Unit Conversion (0) | 2021.12.18 |
---|---|
[백준][C++] 20055: 컨베이어 벨트 위의 로봇 (0) | 2021.09.23 |
[백준][C++] 2417: 정수 제곱근 (0) | 2020.10.30 |
[백준][C++] 10830: 행렬 제곱 (0) | 2020.10.30 |
[백준][C++] 1322: X와 K (0) | 2020.10.29 |