Language Grammar/C++

2024 - 02 - 12 C++ 코딩테스트 10주완성 D+4

Jang_^ 2024. 2. 12. 18:02

*시간복잡도

입력크기에 대해 어떠한 알고리즘이 실행되는데 걸리는 시간이며 주요로직의 반복횟수를 중점으로 측정됨.


*빅오표기법

복잡도에 가장 영향을 많이 끼치는 항의 상수인자를 빼고 나머지 항을 없애서 복잡도를 나타내는 표기법

예) 10n^2 + n 을 빅오표기법으로 나타내면 => 
상수 인자인 10을 빼고 핵심인 n^2 만 빼내 O(n^2) 로 표현

영향을 많이 끼치는 항에 대한 기준은 입력값에 대해서 증가속도가 더 빠르고 많은 항이 기준이다.


*빅오표기법 입력값에 대한 증가속도 순서
n! > 2^n > n^2 > n log n > n > log n , 1

*상수시간 시간복잡도

입력크기와 상관없이 일정한 시간복잡도를 가지는 것을 말함.

시간복잡도 첫번째 예제 실습코드 

int main()
{
    int n;
    cin >> n;
    int a = 0;
    for (int i = 0; i < n; i++) // n = 3이면 0 , 1, 2 
    {
    for (int j = 0; j < i; j++) // n-1 만큼 돌고 
    {
    a += i + j;
    }
    }
    cout << a << '\n';
    return 0;
}



입력받은 n 값이 5일때 기준으로 반복문의 경우를 작성해보면

i = 1 일때, j = 0

i = 2 일때, j = 0,1

i = 3 일때, j = 0,1,2

i = 4 일때, j = 0,1,2,3 이다.

이를 그래프로 그려보면

사각형의 넓이를 구하는 공식은 가로 x 세로 이기때문에 4 x 4 에다 절반이므로 2로 나눠준다.

 j 의 조건문 값이 i 를 포함하지 않는 미만이므로 n값을 빼준다.

따라서 시간복잡도는 1/2(n^2 - n) 이다.

빅오표기법으로 나타내면 상수제외 및 입력값 비례 증가속도가 가장빠른 n^2을 가져오므로 O(n^2) 이다.

시간복잡도 두번째 예제 실습코드

 

void solve(int N, int M)
{
    int a = 1;

    for (int i = 0; i < N; i++)
    {
    a *= i;
    }

    for (int j = 0; j < M; j++)
    {
    a *= j;
    }

    cout << a << "\n";
}

int main()
{
    //Solve 함수에 대한 인자로 받을 지역변수
    int N, M;

    cin >> N >> M;
    solve(N, M);
    return 0;
}


이 경우에는 반복문끼리 덧셈하면 시간복잡도를 구할수 있다.

N 값과 M 값 만큼 반복문을 따로 돌리므로

시간 복잡도는 N + M 이 된다.

만약 하나의 반복문이 아닌 N^2 + N + M^2 + M 같은 여러가지 반복문이 따로 돌고 있을 경우. 
하나의 반복문에서 입력값에 비례해 가장 증가속도가 큰 값을 따로구해 빅오표기법으로 표현한다.

N 값의 경우 가장 증가속도가 큰 값은 N^2 이고 , M 값의 경우 가장 증가속도가 가장 큰값은 M^2 이므로 두값을 더해서 표기한 O(N^2 + M^2) 으로 표현하면 된다

시간복잡도 세번째 예재 실습코드

 

//시간복잡도 세번째 예제
int thirdn, thirda[1004], cnt;

int go(int l, int r)
{
    cnt++;

    if (l == r) return thirda[l];
    int mid = (l + r) / 2;
    int sum = go(l, mid) + go(mid + 1, r);
    return sum;

}

int main()
{
    //시간복잡도 세번째 예제
    cin >> thirdn;
    for (int i = 1; i <= thirdn; i++)
    {
    thirda[i - 1] = i;
    }
    int sum = go(0, thirdn - 1);

    cout << sum << '\n';

    return 0;
}


재귀함수의 경우에는 Cnt 라는 호출마다 증감되는 전역변수를 이용하여

호출이 얼마나 되는지 구해본 뒤, 시간학습도에 대한 식을 추론하여도 됌.

입력값 N에 5 일 경우 9 , 10 일 경우 19이므로


 2n-1 이라는 시간복잡도를 추론할 수 있다.

다른 값을 넣었을 때도 충분히 도출이 가능하기 때문에 시간복잡도는 2n-1 이 되고

이를 빅오표기법으로 하면 상수항을 제외한 O(n) 이 된다.