문제 : https://www.acmicpc.net/problem/16282
[알고리즘 풀이]
이 문제의 핵심은 체인을 빼내면 항상 1g짜리 체인이 생기고, 체인이 1을 기준으로 왼쪽 / 1 / 오른쪽으로 3등분으로
나뉜다. 즉, 우리는 체인을 한 번 빼내면 다음과 같은 3개의 체인을 얻을 수 있다. K(g) / 1(g) / L(g)
우리는 체인을 빼내는 횟수를 최소화하고 싶으므로, i번 체인을 뺐을 때 최대 몇 g까지 표현이 가능한지를 생각해보자.
-체인을 1번 뺌-
K1 / 1 / K2 최대 3등분으로 나눠지고, 2가 없으므로 2가 필요하고, 2 / 1 이 있다고 가정하면 4가 필요하다.
즉, 최대 1번 체인을 빼서 1 + 2 + 4 = 7g 까지 표현이 가능하다.
-체인을 2번 뺌-
K1 / 1 / K2 / 1 / K3 최대 5등분으로 나눠지고, 1이 2개 있으므로 3이 필요하고, 1 + 1 + 3 = 5 이므로 6이 필요하고,
1 + 1 + 3 + 6 = 11이므로 12가 필요하다.
즉, 최대 2번 체인을 빼서 1 + 1 + 3 + 6 + 12 = 23g 까지 표현이 가능하다.
-체인을 i번 뺌-
i번 체인을 빼내면 1g짜리 체인이 i개 생긴 것이고, 최대 2 * i + 1개의 체인으로 나눠진다.
그러면 1g까지라 i개 있으므로, (i + 1) g짜리 체인이 필요하고,
그다음엔 1 * i + (i + 1) g까지는 표현이 가능하므로, (2 * i + 1) g짜리 체인이 필요하다.
이 과정을 반복하면 i번 체인을 빼냈을 때, 최대 2^(i + 1) * i + 2^(i+1) - 1 g까지 표현이 가능하다.
따라서, 체인을 빼내는 횟수를 늘려가며 최대 표현 가능한 g보다 n이 작아지는 순간 출력해주면 된다.
#include<iostream>
using namespace std;
int main(void) {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
long long n;
cin >> n;
for (long long i = 1; ; i++) {
long long total = i;
for (int j = 0; j <= i; j++)
total = total + (total + 1);
if (n <= total){
cout << i;
return 0;
}
}
}
'Problem Solving > ICPC' 카테고리의 다른 글
[ICPC][BOJ] 16288 - Passport Control (0) | 2019.09.28 |
---|---|
[ICPC][BOJ] 16287 - Parcel (0) | 2019.09.28 |
[ICPC][BOJ] 16283 - Farm (0) | 2019.09.28 |
[ICPC][BOJ] 13328 - Message Passing (0) | 2019.09.23 |
[ICPC][BOJ] 13333 - 'Q-Index' (0) | 2019.09.23 |