一行目に数の個数 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
エラー一覧00F8 ↓ · ⇧F8 ↑
入力(stdin)
実行すると、これらの行が順に input()・標準入力に渡されます(実行中に入力を求めません)。
$ 準備完了
コードを入力して解くにはパソコンで開いてください。モバイルでは問題と解答を見られます。
ほかの言語では?言語別の解答を見る · 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) と Craykon a.部分リスト(s, k)(韓国語 a.부분목록(s, k))は個数を受け取ります。 C には切り出しがないので s から k 個を回して書きます。 JS で a.slice(s, k) のように個数を入れると窓が狂うのが一つ目の落とし穴です。 二つ目は切り捨て:C printf("%.2f")、Python f"{x:.2f}"、Craykon 文字.桁そろえ(x, 2) はどれも四捨五入なので 2/3 が 0.67 になります。 合計に 100 を掛けて整数の割り算(best * 100 / k、Python //、Craykon 数学.商)で切り捨て、商と余りから 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 + 1print(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"));