https://www.acmicpc.net/problem/10025
코드설명
슬라이딩 윈도우(Sliding Window) 를 활용합니다.
문제에서 가장 헷갈린 점은, Sliding Window에서 주어진 K를 (K*2 +1)로 처리한뒤 이것을 일종의 간격이라고 생각하는 것 입니다.
for(int i=(K * 2 + 1) - 1; i<=1000000; i++) { slidingSum += ice[i]; answer = Math.max(answer, slidingSum); slidingSum -= ice[i - (K * 2 + 1) + 1]; }
i - (K*2+1) +1 을 통해서 i번쨰 위치에서 - (K*2+1) + 1 만큼의 앞쪽으로 이동하여 빼주고, 하는 과정을 유의합니다.
만약 K가 500000이라면, 모든 양동이들의 위치보다 더 커집니다. 그러므로 ArrayIndexOutOfRange가 발생할 수 있는데, 이 경우에는 최대값이므로 모든 양동이를 다 움직여서 가져갈 수 있으므로 다 더해서 반환합니다.
//만약 K가 500000이라면, 모든 양동이를 다 움직여서 가져갈 수 있으므로 다 더해서 반환한다. if( (K * 2 + 1) >= 1000000) { for(int i=0; i<=1000000; i++) { answer += ice[i]; } System.out.println(answer); return ; }
혹은, 아래와 같이 더 깔금하게 처리할 수 있습니다.
for(int i=0; i< (K * 2 + 1) - 1 && i<= 1000000; i++) { slidingSum += ice[i]; } answer = Math.max(answer, slidingSum);
코드
정답코드 1입니다.
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.StringTokenizer; public class Main { private static int N, K; private static int answer = 0; private static int slidingSum = 0; private static int[] ice; public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); K = Integer.parseInt(st.nextToken()); ice = new int[1000001]; for(int i=0;i<N;i++) { st = new StringTokenizer(br.readLine()); int g = Integer.parseInt(st.nextToken()); int x = Integer.parseInt(st.nextToken()); ice[x] += g; } //만약 K가 500000이라면, 모든 양동이를 다 움직여서 가져갈 수 있으므로 다 더해서 반환한다. if( (K * 2 + 1) >= 1000000) { for(int i=0; i<=1000000; i++) { answer += ice[i]; } System.out.println(answer); return ; } for(int i=0; i< (K * 2 + 1) - 1; i++) { slidingSum += ice[i]; } for(int i=(K * 2 + 1) - 1; i<=1000000; i++) { slidingSum += ice[i]; answer = Math.max(answer, slidingSum); slidingSum -= ice[i - (K * 2 + 1) + 1]; } System.out.println(answer); } }
K가 범위를 벗어날경우를 반복문 조건문에 조건을 넣어서 처리 그리고 answer 갱신.
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.StringTokenizer; public class Main { private static int N, K; private static int answer = 0; private static int slidingSum = 0; private static int[] ice; public static void main(String[] args) throws IOException{ BufferedReader br = new BufferedReader(new InputStreamReader(System.in)); StringTokenizer st = new StringTokenizer(br.readLine()); N = Integer.parseInt(st.nextToken()); K = Integer.parseInt(st.nextToken()); ice = new int[1000001]; for(int i=0;i<N;i++) { st = new StringTokenizer(br.readLine()); int g = Integer.parseInt(st.nextToken()); int x = Integer.parseInt(st.nextToken()); ice[x] += g; } //만약 K가 500000이라면, 모든 양동이를 다 움직여서 가져갈 수 있으므로 다 더해서 반환한다. // if( (K * 2 + 1) >= 1000000) { // for(int i=0; i<=1000000; i++) { // answer += ice[i]; // } // System.out.println(answer); // return ; // } for(int i=0; i< (K * 2 + 1) - 1 && i<= 1000000; i++) { slidingSum += ice[i]; } answer = Math.max(answer, slidingSum); for(int i=(K * 2 + 1) - 1; i<=1000000; i++) { slidingSum += ice[i]; answer = Math.max(answer, slidingSum); slidingSum -= ice[i - (K * 2 + 1) + 1]; } System.out.println(answer); } }