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);
	}
    
}

 

+ Recent posts