{ }codelper
목록 자르기누적 계산평균P0106

가장 좋은 연속 구간의 평균

첫 줄에 수의 개수 n과 창 크기 k가, 둘째 줄에 수 n개가 빈칸 하나씩으로 나뉘어 주어진다.
연속한 k개의 수를 하나의 창이라고 한다.
합이 가장 큰 창을 찾아라.
합이 가장 큰 창이 여럿이면 가장 왼쪽 창을 고른다.
첫 줄에 그 창이 시작하는 자리(1부터 센다)를 출력한다.
둘째 줄에 그 창의 수 k개를 빈칸 하나씩으로 나눠 출력한다.
셋째 줄에 그 창의 평균을 소수 둘째 자리까지 출력한다.
평균은 반올림하지 않고, 정확한 값(합 ÷ k)에서 소수 셋째 자리부터 버린다(예: 11 / 3 = 3.666… → 3.66, 7 / 2 → 3.50).

입력
1 ≤ k ≤ n ≤ 10,000, 0 ≤ 각 수 ≤ 1000(정수)
출력
세 줄: 시작 자리, 창의 수 k개, 소수 둘째 자리까지 버린 평균
예시 1 · stdin
7 3
1 5 2 4 4 1 2
stdout
2
5 2 4
3.66
예시 2 · stdin
5 2
4 3 1 2 5
stdout
1
4 3
3.50
main.py
입력(stdin)

실행하면 이 줄들이 차례로 input()·표준 입력으로 들어가요(실행 중에 묻지 않아요).

$ 준비됐어요

코드를 입력해 풀려면 PC에서 열어 주세요. 모바일에서는 문제와 풀이를 볼 수 있어요.

다른 언어로는?언어별 풀이 보기 · 8개 언어 풀이

창마다 k개를 새로 더하면 n × k번 계산해요.
대신 누적으로, 한 칸 밀 때 들어온 수를 더하고 빠진 수를 빼면(total += a[i] - a[i - k]) n번이면 끝나요.
고른 창을 잘라 내는 법은 언어마다 두 번째 값의 뜻이 달라요: Python a[s:s + k], JS·TS a.slice(s, s + k), Java Arrays.copyOfRange(a, s, s + k), C++ vector(a.begin() + s, a.begin() + s + k)는 끝 자리(그 자리는 빼고)를 받고, C# GetRange(s, k)와 크레이콘 a.부분목록(s, k)는 개수를 받아요.
C에는 자르기가 없어서 s부터 k개를 돌며 써요.
JS에서 a.slice(s, k)처럼 개수를 넣으면 창이 틀려지는 게 첫 함정이에요.
둘째 함정은 버림: C printf("%.2f"), Python f"{x:.2f}", 크레이콘 글자.소수자리맞추기(x, 2)는 모두 반올림이라 2/3이 0.67이 돼요.
합에 100을 곱해 정수 나눗셈(best * 100 / k, Python //, 크레이콘 수학.몫)으로 버린 뒤 몫과 나머지로 3.66을 만들어요.
실수로 Math.floor(best / k * 100)처럼 버리면 0.29 × 100이 28.999…라서 0.28이 되니, 정수로만 계산해요(합 × 100은 최대 10⁹이라 int에 들어가요).
셋째 함정은 동점: >=로 바꾸면 오른쪽 창이 남아요.
창은 모두 n − k + 1개라서 반복을 하나 덜 돌면 마지막 창을 놓쳐요.

Pythonmain.py · 15 줄
n, k = map(int, input().split())a = list(map(int, input().split())) # 첫 창의 합을 구한 뒤, 한 칸씩 밀며 새로 들어온 수를 더하고 빠진 수를 뺀다total = sum(a[:k])best, start = total, 0for i in range(k, n):    total += a[i] - a[i - k]    if total > best:          # 같으면 바꾸지 않는다 → 맨 왼쪽 창이 남는다        best, start = total, i - k + 1 print(start + 1)print(*a[start:start + k])t = best * 100 // k           # 소수 둘째 자리까지 버림(정수로 계산)print(f"{t // 100}.{t % 100:02d}")
JavaScriptmain.js · 17 줄
const [n, k, ...a] = require("fs").readFileSync(0, "utf8").trim().split(/\s+/).map(Number); let total = 0;for (let i = 0; i < k; i++) total += a[i];let best = total, start = 0;for (let i = k; i < n; i++) {  total += a[i] - a[i - k];  if (total > best) {    best = total;    start = i - k + 1;  }} const t = Math.floor((best * 100) / k); // 소수 둘째 자리까지 버림console.log(start + 1);console.log(a.slice(start, start + k).join(" ")); // slice(시작, 끝) — 끝은 빼고console.log(`${Math.floor(t / 100)}.${String(t % 100).padStart(2, "0")}`);
TypeScriptmain.ts · 18 줄
import { readFileSync } from "node:fs";const [n, k, ...a]: number[] = readFileSync(0, "utf8").trim().split(/\s+/).map(Number); let total = 0;for (let i = 0; i < k; i++) total += a[i];let best = total, start = 0;for (let i = k; i < n; i++) {  total += a[i] - a[i - k];  if (total > best) {    best = total;    start = i - k + 1;  }} const t: number = Math.floor((best * 100) / k); // 소수 둘째 자리까지 버림console.log(start + 1);console.log(a.slice(start, start + k).join(" ")); // slice(시작, 끝) — 끝은 빼고console.log(`${Math.floor(t / 100)}.${String(t % 100).padStart(2, "0")}`);
JavaMain.java · 33 줄
import java.io.*;import java.util.*; public class Main {    public static void main(String[] args) throws IOException {        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));        StringTokenizer st = new StringTokenizer(br.readLine());        int n = Integer.parseInt(st.nextToken()), k = Integer.parseInt(st.nextToken());        int[] a = new int[n];        st = new StringTokenizer(br.readLine());        for (int i = 0; i < n; i++) a[i] = Integer.parseInt(st.nextToken());         int total = 0;        for (int i = 0; i < k; i++) total += a[i];        int best = total, start = 0;        for (int i = k; i < n; i++) {            total += a[i] - a[i - k];            if (total > best) {                best = total;                start = i - k + 1;            }        }         // copyOfRange(배열, 시작, 끝) — 끝은 빼고        int[] window = Arrays.copyOfRange(a, start, start + k);        StringJoiner sj = new StringJoiner(" ");        for (int x : window) sj.add(String.valueOf(x));        int t = best * 100 / k; // 정수 나눗셈 = 버림(값이 음수가 아니므로)        System.out.println(start + 1);        System.out.println(sj);        System.out.printf("%d.%02d%n", t / 100, t % 100);    }}
C#Main.cs · 31 줄
using System;using System.Collections.Generic;using System.Linq; class Program{    static void Main()    {        int[] nk = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToArray();        int n = nk[0], k = nk[1];        List<int> a = Console.ReadLine().Split(' ', StringSplitOptions.RemoveEmptyEntries).Select(int.Parse).ToList();         int total = 0;        for (int i = 0; i < k; i++) total += a[i];        int best = total, start = 0;        for (int i = k; i < n; i++)        {            total += a[i] - a[i - k];            if (total > best)            {                best = total;                start = i - k + 1;            }        }         int t = best * 100 / k; // 정수 나눗셈 = 버림(값이 음수가 아니므로)        Console.WriteLine(start + 1);        Console.WriteLine(string.Join(" ", a.GetRange(start, k))); // GetRange(시작, 개수)        Console.WriteLine($"{t / 100}.{t % 100:D2}");    }}
C++main.cpp · 29 줄
#include <iomanip>#include <iostream>#include <vector> int main() {    int n, k;    std::cin >> n >> k;    std::vector<int> a(n);    for (int& x : a) std::cin >> x;     int total = 0;    for (int i = 0; i < k; i++) total += a[i];    int best = total, start = 0;    for (int i = k; i < n; i++) {        total += a[i] - a[i - k];        if (total > best) {            best = total;            start = i - k + 1;        }    }     // 반복자 두 개(시작, 끝)로 잘라 새 vector를 만든다    std::vector<int> window(a.begin() + start, a.begin() + start + k);    std::cout << start + 1 << "\n";    for (size_t i = 0; i < window.size(); i++) std::cout << (i ? " " : "") << window[i];    std::cout << "\n";    int t = best * 100 / k; // 정수 나눗셈 = 버림    std::cout << t / 100 << "." << std::setw(2) << std::setfill('0') << t % 100 << "\n";}
Cmain.c · 28 줄
#include <stdio.h> static int a[10000]; int main(void) {    int n, k;    scanf("%d %d", &n, &k);    for (int i = 0; i < n; i++) scanf("%d", &a[i]);     int total = 0;    for (int i = 0; i < k; i++) total += a[i];    int best = total, start = 0;    for (int i = k; i < n; i++) {        total += a[i] - a[i - k];        if (total > best) {            best = total;            start = i - k + 1;        }    }     printf("%d\n", start + 1);    /* C에는 자르기가 없다: 시작 자리부터 k개를 돈다 */    for (int i = start; i < start + k; i++) printf(i > start ? " %d" : "%d", a[i]);    printf("\n");    int t = best * 100 / k; /* 정수 나눗셈 = 버림 */    printf("%d.%02d\n", t / 100, t % 100);    return 0;}
Craykonmain.cray · 28 줄
첫줄 = 콘솔.수들읽기();n = 첫줄[0];k = 첫줄[1];a = 콘솔.수들읽기(); // 첫 창의 합을 구한 뒤, 한 칸씩 밀며 새로 들어온 수를 더하고 빠진 수를 뺀다합 = 0;반복 (i = 0; i < k; i++){    합 += a[i];}best = 합;start = 0;반복 (i = k; i < n; i++){    합 += a[i] - a[i - k];    만약 (합 > best)    {        best = 합;        start = i - k + 1;    }} 콘솔.쓰기(start + 1);콘솔.쓰기(a.부분목록(start, k));t = 수학.몫(best * 100, k);소수부 = "" + t % 100;콘솔.쓰기(수학.몫(t, 100) + "." + 소수부.앞채우기(2, "0"));