DY N DY

BOJ 11003 최소값 찾기(C++) 본문

PARK/ALGORITHM

BOJ 11003 최소값 찾기(C++)

손세지 2016. 8. 30. 13:14
시간 제한메모리 제한제출정답맞은 사람정답 비율
3 초256 MB64318810631.832%

문제

N개의 수 A1, A2, ..., AN과 L이 주어진다.

Di = Ai-L+1 ~ Ai 중의 최소값이라고 할 때, D에 저장된 수를 출력하는 프로그램을 작성하시오. 이 때, i ≤ 0 인 Ai는 무시하고 D를 구해야 한다.

입력

첫째 줄에 N과 L이 주어진다. (1 ≤ L ≤ N ≤ 5,000,000)

둘째 줄에는 N개의 수 Ai가 주어진다. (-109 ≤ Ai ≤ 109)

출력

첫째 줄에 Di를 공백으로 구분하여 순서대로 출력한다.

예제 입력 

12 3
1 5 2 3 6 2 3 7 3 5 2 6

예제 출력 

1 1 1 2 2 2 2 2 3 3 2 2

힌트

출처

알고리즘 분류



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include    <stdio.h>
#pragma warning (disable:4996)
int A[5555555];
int dq[5555555];
int front = 100;
int rear = 100;
 
int main()
{
    int N, L;
    scanf("%d %d", &N, &L);
    for (int i = 1; i <= N; ++i)
    {
        scanf("%d", &A[i]);
 
        if (front == rear) //deque가 비어어져있는 경우 앞에 넣어준다.
            dq[--front] = A[i];
        else
        {
            while (front != rear && dq[rear-1] > A[i])
                dq[--rear] = 0;
            dq[rear++] = A[i];
        }
        if (i > L && dq[front] == A[i - L]) dq[front++] = 0;
 
        printf("%d ", dq[front]);
    }
    return 0;
}


dequeue(min heap)를 사용한 문제. 

처음 풀 때는 

최소값을 저장해 두고, 최소값이 여전히 해당 윈도우 내에 있다면 추가되는 값과의 비교만 하면 된다고 생각했는데

최악의 경우를 고려하지 않았다. 최악의 경우 계속 최소값을 다시 찾게 되면 시간초과가 나게 된다. 

N개의 수 중 L개의 범위 내의 최소값이므로 최악의 경우 대략적으로 N*L이 될 수 있다. 


위의 문제는 해당 윈도우 내에 최소값을 다시 찾아야 할 경우를 대비하지 않았다는 것인데, 이를 해결하려면 현재의 최소값 뿐만 아니라

2위값, 3위값 등을 후보 값들을 저장해야 한다. 

이를 min heap을 이용하면 해결하여 연산을 상당히 줄일 수 있다. 

1 5 2 3 6 2 3 7 3 5 2 6이 들어온다고 할 경우 

1을 min heap에 넣어준다. 

5는 1보다 크지만 1과 5중에 2등 후보가 될 수 있다. 넣어준다. - 여전히 min heap이므로 root node는 가장 작은 1이 된다.

2는 1보다 크지만 5보다 작다. 2까지 왔을 때 5는 더이상 어떤 윈도우에서도 후보가 될 수 없게 된다. 때문에 더이상 신경쓰지 않아도 되므로 빼준다.

뺀 후에 2를 넣어준다. 

1 2가 들어있으므로 1이 사라지는 위치가 될 때 자동적으로 2라는 후보(2등)가 root node가 된다. 

3이 들어올 경우 

1, 2보다 크기 때문에 후보가 될 수 있으므로 넣어준다. 

1, 2, 3이 들어가게 되는데 1의 경우 3이 들어올 때 이미 고려하지 않아도 되는 위치가 되므로 제거해준다. 

자연스럽게 2가 최소값이 된다. 


이런 순서로 힙을 이용하게 되면 

삽입, 삭제 하는데 각각 O(logN)이 되므로 

모든 N을 돌며 삽입, 삭제하므로 대략 O(NlogN)의 시간복잡도를 가진다고 할 수 있다. 


'PARK > ALGORITHM' 카테고리의 다른 글

BOJ 2294 동전2(C++)  (0) 2016.08.30
BOJ 2749 피보나치 수 3(C++)  (1) 2016.08.30
BOJ 1727 커플만들기(C++)  (0) 2016.08.30
BOJ 2590 색종이(C++)  (0) 2016.08.30
BOJ 2420 사파리월드(C++)  (0) 2016.08.30