문제 : FESTIVAL
N이 최대 1000 이므로 O(N^2)의 알고리즘이라도 충분히 통과할 수 있다. 따라서 단순히 차이가 L 이상인 모든 구간에 대해 O(N^2)으로 확인해주면 된다. (코드의 24~25 line 참고)
주의점은 10^(-7) 이하의 절대/상대 오차가 있어야 하므로, 그냥 바로 출력하면 안되고 소수점 8자리 이상을 출력하도록 해야 한다. 자바의 경우 String.format("%.8f", answer)과 같은 코드로(c언어와 비슷한 출력 방식) 소수점 8자리까지 출력할 수 있다.
그리고 모든 구간에 대해 직접 더해봐도 시간 제한에 충분히 맞출 수 있긴 하지만(O(N)), prefix sum을 미리 구해둘 경우 [a, b] 구간의 합은 arr[b]-arr[a-1] 과 같이 O(1)로 구할 수 있다(코드의 7 line).
코드 : github
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.util.StringTokenizer;
public class Main {
private double getAverageFee(int[] prefixSum, int i, int j) {
int sum = prefixSum[j] - prefixSum[i-1];
return (double)sum / (j-i+1);
}
private void solution() throws Exception {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int c = Integer.parseInt(br.readLine());
StringBuilder sb = new StringBuilder();
while (c-->0) {
StringTokenizer st = new StringTokenizer(br.readLine());
int n = Integer.parseInt(st.nextToken());
int l = Integer.parseInt(st.nextToken());
int[] prefixSum = new int[n+1];
st = new StringTokenizer(br.readLine());
for (int i = 1; i <= n; i++) {
prefixSum[i] = prefixSum[i-1] + Integer.parseInt(st.nextToken());
}
double answer = Double.MAX_VALUE;
for (int i = 1; i <= n-l+1; i++) {
for (int j = i+l-1; j <= n; j++) {
double curAverage = getAverageFee(prefixSum, i, j);
if (answer > curAverage)
answer = curAverage;
}
}
sb.append(String.format("%.8f\n", answer));
}
System.out.print(sb);
}
public static void main(String[] args) throws Exception {
new Main().solution();
}
}
'Study > 알고리즘 문제해결전략(종만북)' 카테고리의 다른 글
[종만북] WILDCARD - Wildcard (자바 java) (0) | 2023.04.02 |
---|---|
[종만북] CLOCKSYNC - Synchronizing Clocks (자바 java) (0) | 2023.03.20 |
[종만북] BOARDCOVER - 게임판 덮기 (자바 java) (0) | 2023.03.20 |
[종만북] PICNIC - 소풍 (자바 java) (0) | 2023.03.20 |
[종만북] BOGGLE - 보글 게임 (자바, C++) (0) | 2023.03.20 |
댓글