-
[KOITP] Sliding Windows자료구조 및 알고리즘/문제풀이 2017. 1. 12. 08:01
출 처 : http://koitp.org/problem/SLIDING_WINDOWS/read/
시간 제한 메모리 제한 제출 횟수 정답 횟수 (비율) 정답자 수 3.0 초 512 MB 825 97 (12%) 76 < Comment >
Deque 를 이용하여 문제를 풀었는데, 생각보다 발상 자체는 단순한데, 막상 안 쓰던 자료구조를 쓰려니 헷갈리기도 해서 소스코드가 뭔가 지져분해졌습다. 기본 아이디어는 심플하게 현재 입력받은 값보다 큰 값이 자신보다 앞쪽에 들어가 있으면, 이 경우에는 뒤에서부터 차례대로 빼주고 자신을 더해줍니다. 결국 항상 최대값이 맨 앞에 남아있을 것이고, 이 점을 이용하여 문제를 풀었습니다. 최소값의 경우도 마찬가지이고, 다만 주어진 K의 크기를 넘어서게 되면, 이 경우에는 범위를 넘어서므로, 맨 앞쪽에 있는 최대값이 혹여 범위를 벗어나는 경우에는 제거를 해 주는 식으로, 진행했습니다.
import java.io.BufferedReader; import java.io.BufferedWriter; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.util.ArrayDeque; import java.util.Deque; import java.util.StringTokenizer; public class SlidingWindows { public static int N = 0; public static int K = 0; public static int arr[] = null; public static long min[] = null; public static long max[] = null; public static long sum[] = null; public static void main(String[] args) throws Exception { BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(System.out)); StringTokenizer st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); K = Integer.parseInt(st.nextToken()); arr = new int[N+1]; min = new long[N+1]; max = new long[N+1]; sum = new long[N+1]; st = new StringTokenizer(br.readLine()); for (int i = 1 ; i <= N ; i++) { arr[i] = Integer.parseInt(st.nextToken()); } Deque<Integer> dq = new ArrayDeque<>(); Deque<Integer> IdxDq = new ArrayDeque<>(); for (int i = 1 ; i <= N ; i++) { while(!dq.isEmpty()) { if (dq.peekLast() < arr[i]) { dq.pollLast(); IdxDq.pollLast(); } else { break; } } dq.addLast(arr[i]); IdxDq.addLast(i); while (IdxDq.peekLast() - IdxDq.peekFirst() >= K) { dq.pollFirst(); IdxDq.pollFirst(); } max[i] = dq.peekFirst(); } while(!dq.isEmpty()) { dq.pollLast(); } while(!IdxDq.isEmpty()) { IdxDq.pollLast(); } for (int i = 1 ; i <= N ; i++) { while(!dq.isEmpty()) { if (dq.peekLast() > arr[i]) { dq.pollLast(); IdxDq.pollLast(); } else { break; } } dq.addLast(arr[i]); IdxDq.addLast(i); while (IdxDq.peekLast() - IdxDq.peekFirst() >= K) { dq.pollFirst(); IdxDq.pollFirst(); } min[i] = dq.peekFirst(); } for (int i = 1 ; i <= N ; i++) { sum[i] = sum[i-1] + arr[i]; } for (int i = K ; i <= N ; i++) { bw.write("" + min[i] + " " + max[i] + " " + (sum[i] - sum[i - K]) + "\n"); } bw.flush(); bw.close(); } }