/*
このコード、と～おれ!
Be accepted!
∧＿∧　
（｡･ω･｡)つ━☆・*。
⊂　　 ノ 　　　・゜+.
　しーＪ　　　°。+ *´¨)
 　　　　　　　　　.· ´¸.·*´¨) ¸.·*¨)
			　　　　　　　　　　(¸.·´ (¸.·'* ☆
					*/

#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <map>
#include <string>
#include <climits>
#include <tuple>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <cmath>
#include <algorithm>
#include <memory>
#include <iomanip>
#define rep(i, n) for(Int (i) = 0; (i) < (n); ++(i))
#define debug(var) cout << #var << ": " << var << endl
using namespace std;
using Int = int64_t;
using Double = double;
using Uint = uint64_t;
constexpr Uint mod = 1e9 + 7;
constexpr Int INF = INT_MAX;
using Container = vector<Int>;
template<typename T>
using Grid = vector<vector<T>>; // 二次元配列。[y][x]
template<typename T, typename U>
using Umap = unordered_map<T, U>;
template<typename T>
using Uset = unordered_set<T>;
template<typename T>
using P = pair<T, T>;

//a, a + 1, a + 2, ... , b - 1, bの総和を求める関数(a <= b)。計算量はO(1)
Int Sum(Int a, Int b) {
	if (b < a)return 0;
	if ((b - a + 1) % 2 == 0)return (a + b) * (b - a + 1) / 2;
	else return (a + b) * ((b - a + 1) / 2) + (a + b) / 2;
}

//This sample is RMQ. Change a little difference by yourself.
template<typename Function>
class SegmentTree {
public:
	Int invalid_value = 0;
	Int depth = 1;
	Int leaf_size, tree_size, arr_size;
	Function f;
	Container data;

	//計算量はO(n)。*nは配列の長さ
	SegmentTree(Container arg, Function func)
		: f(func) {
		arr_size = arg.size();
		Int n = 1;
		tree_size = 1;

		while (n < arr_size) {//完全二分木にするため2^n > lenとなる最小の2^nを求める
			n *= 2;
			tree_size += n;
			depth++;
		}
		leaf_size = n;
		data.resize(tree_size);//木の配列のサイズを初期化

		for (Int i = 0; i < n; ++i) {//葉の値を初期化
			if (i <= arr_size - 1)data[n + i - 1] = arg[i];
			else data[n + i - 1] = invalid_value;
		}

		Int tmp_size = leaf_size;
		for (Int i = 0; i < depth - 1; ++i) {
			for (Int j = 0; j < tmp_size / 2; ++j) {//ノードは(j * 2, j * 2 + 1)
				data[(tmp_size + j * 2 - 2) / 2] = f(data[tmp_size + j * 2 - 1], data[tmp_size + j * 2]);
			}
			tmp_size /= 2;
		}

	}

	//k番目の配列の値をvalに変える。計算量はO(log n)
	void update(Int k, Int val) {
		//木のインデックスに変える
		k += leaf_size - 1;
		data[k] = val;
		//再帰的に更新する
		while (k > 0) {
			k = (k - 1) / 2;
			data[k] = f(data[k * 2 + 1], data[k * 2 + 2]);
		}
	}

	//[a, b)のクエリを返す。使うときはquery(a, b)で呼び出してね。計算量はO(log n)
	Int query(Int a, Int b, Int k = 0, Int l = 0, Int r = -1) {
		if (r < 0)r = leaf_size;
		if (r <= a || b <= l)return invalid_value;
		if (a <= l && r <= b)return data[k];
		Int vl = query(a, b, k * 2 + 1, l, (l + r) / 2);
		Int vr = query(a, b, k * 2 + 2, (l + r) / 2, r);
		return f(vl, vr);
	}
};

template<typename Function>
SegmentTree<Function> make_SegmentTree(Container arg, Function func) {
	SegmentTree<Function> seg(arg, func);
	return seg;
}

int main() {

	Int N, K; cin >> N >> K;
	Container p(N);
	rep(i, N)cin >> p[i];
	auto seg = make_SegmentTree(p, [](Int a, Int b) {return a + b; });

	Int begin = -1;
	Int sum = -1;
	//和が最大の部分列を探索する。
	rep(i, N - K + 1) {
		if (seg.query(i, i + K) > sum) {
			begin = i;
			sum = seg.query(i, i + K);
		}
	}

	Double ans = 0.f;
	for (Int i = begin; i < begin + K; ++i) {
		ans += ((Double)Sum(1, p[i]) / (Double)p[i]);
	}

	cout << setprecision(7) << ans << endl;

}

Measured memory_bytes: 9088