881 words
4 minutes
[BOJ] 두 배
| TimeLimit | MemoryLimit | Condition | TAG | 
|---|---|---|---|
| 1s | 1024MB | (1<=N <= 250000, 1 <= A_i <= 1000000) | Math(수학) | 
저는 처음 접근할 때, 범위를 제대로 보지 않고서 접근하다가 아예 이분탐색을 돌려버렸습니다. 그러다가 진짜 왜 틀린지 모르고 있다가 범위를 알고나서 부터 이분 탐색이라는 방법말고 다른 방법을 떠오르게 되었어요.
이제 그 아이디어에 대해서 말해보겠습니다.
일단 정의부터 시작하여 아이디어의 기초적인 기반을 다져봅시다.
-> then 
-> 
-> 
-> 
-> 
지금 여기서 ceil(올림)이 사용되는 이유는 나눴을 때, x.n(x>=0인 정수, n!=0)이 나오는 꼴이면 최소 곱을 알고 싶기 때문에 이것보다 더 크다면 우리는 x보다 크고 최대한 작은 값을 고르면 된다. 그래서 올림을 통해서 이를 해결한다.
이것을 통해서 알 수 있는 것은 이건 오류가 발생할 가능성이 존재한다는 것이다. (저는 코드짜서 넣고 그 다음에 블로그 쓰면서 생각해보니 이렇더라구요… 완벽한 코드는 아닌 것 같아 남깁니다..)
정답 코드
#include <iostream>
#include <cmath>
using namespace std;
using ll = unsigned long long;
int n;
int board[250'001];
int results[250'001];
int solution(int current){
    return max((int)(log2((double)board[current-1] / (double)board[current]) + (double)results[current - 1]), 0);//board[current-1])
}
int main(){
    // i번까지 모든 조건이 만족한다고 하면, i+1번은 i번보다 크다 2를 곱하는 과정을 반복문으로 하는 것이 아니라 바로 몇 번 곱해야 하는지 알 수 있는 방법을
    // 찾아보자 -> 그냥 수학으로 풀어야하는 거다!
    
    // N_i를 A라고 하자. N_{i+1}을 B라고 하자.
    // N_i * 2^x <= N_{i+1} * 2^y
    // (N_i*2^x)/N_{i+1} <= 2^y
    
    // 저기 y를 어떻게 내리냐 log 씌우면 될라나
    // (x + log_2(N_i)/log_2(N_{i+1}) <= y
    // 옹 나왔따! 근데 정답이 integer데 어떻게 나오냐
    // 아 그거구나
    // 그냥 올림처리하면 될라나
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n;
    cin >> n;
    for(int i = 0; i < n; i++) cin >> board[i];
    
    ll result = 0;
    for(int i = 1; i < n; i++) {
        results[i] = solution(i); result += results[i];
//        cout << results[i] << " ";
    }
//    cout << "\n";
    
    
    cout << result;
    return 0;
}
