쾌락없는 책임 (공부)/알고리즘 문제풀이
11003 백준 최솟값 찾기 - C++, 덱
허스크
2021. 9. 16. 22:59
반응형
11003번: 최솟값 찾기
N개의 수 A1, A2, ..., AN과 L이 주어진다. Di = Ai-L+1 ~ Ai 중의 최솟값이라고 할 때, D에 저장된 수를 출력하는 프로그램을 작성하시오. 이때, i ≤ 0 인 Ai는 무시하고 D를 구해야 한다.
www.acmicpc.net
#include <iostream>
#include <deque>
using namespace std;
int numbers[5000001];
int n, l;
int main(){
ios_base::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin >> n >> l;
for(int i = 0; i < n; i++)
cin >> numbers[i];
deque<pair<int, int> > list;
for(int i = 0; i < n; i++){
if(!list.empty() && list.front().second < i - l + 1)
list.pop_front();
while(!list.empty() && list.back().first > numbers[i]){
list.pop_back();
}
list.push_back(make_pair(numbers[i], i));
cout << list.front().first << " ";
}
cout << '\n';
}
/*
1 5 2 3 6 2 3 7 3 5 2 6
D(i) = A(i - l + 1) ~ A(i)
범위 = 윈도우가 l이란 뜻
*/
이전 네트워크 수업에서 슬라이딩 윈도우 개념을 공부를 해서 쉬운 문제라고 생각을 했는데 처음 제출에서 시간 초과가 나서 당황을 한 문제였습니다. 생각을 해 보니 아래 코드가 문제였습니다.
for(int j = 0; j < l; j++){
if(!list.empty() && list.back().first > numbers[i])
list.pop_back();
}
위 정답에서 while문 대신 제출했던 for문으로 역할은 슬라이딩 윈도우에서 뒷 부분을 빼는 부분이었습니다. 그런데 위 방법을 사용할 경우 l 길이만큼 무조건 탐색을 강제하기 때문에 시간초과가 나게 됩니다. (l이 500만까지 가능) 그래서 이를 while문으로 대체해 슬라이딩 윈도우에서 필요한 부분들만 빼기 때문에 연산을 줄여 시간초과를 피할 수 있었습니다.
반응형