Problem:
Score : 300 points

Problem Statement

There are N candles placed on a number line.
The i-th candle from the left is placed on coordinate x_i.
Here, x_1 < x_2 < ... < x_N holds.

Initially, no candles are burning.
Snuke decides to light K of the N candles.

Now, he is at coordinate 0.
He can move left and right along the line with speed 1.
He can also light a candle when he is at the same position as the candle, in negligible time.

Find the minimum time required to light K candles.

Constraints

1 \leq N \leq 10^5

1 \leq K \leq N

x_i is an integer.

|x_i| \leq 10^8

x_1 < x_2 < ... < x_N

Input

Input is given from Standard Input in the following format:

N K
x_1 x_2 ... x_N

Output

Print the minimum time required to light K candles.

Sample Input 1

5 3
-30 -10 10 20 50

Sample Output 1

40

He should move and light candles as follows:

Move from coordinate 0 to -10.

Light the second candle from the left.

Move from coordinate -10 to 10.

Light the third candle from the left.

Move from coordinate 10 to 20.

Light the fourth candle from the left.

Sample Input 2

3 2
10 20 30

Sample Output 2

20

Sample Input 3

1 1
0

Sample Output 3

0

There may be a candle placed at coordinate 0.

Sample Input 4

8 5
-9 -7 -4 -3 1 2 3 4

Sample Output 4

10

Solution in C (GCC 5.4.1) (judge verdict: Accepted)

#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

// 内部定数
#define D_COL_CNT		2										// 列数
#define D_CANDLE_MAX	100000									// 最大ろうそく数

// 内部変数
static FILE *szpFpI;											// 入力
static int si2Candle[D_COL_CNT][D_CANDLE_MAX];					// ろうそく
static int si1CCnt[D_COL_CNT];									// ろうそく数

// 内部変数 - テスト用
#ifdef D_TEST
	static int siRes;
	static FILE *szpFpA;
#endif

// ソート関数 - int昇順
int
fSortFnc(
	const void *pzpVal1			// <I> 値１
	, const void *pzpVal2		// <I> 値２
)
{
	int *lipVal1 = (int *)pzpVal1;
	int *lipVal2 = (int *)pzpVal2;

	// 昇順
	if (*lipVal1 > *lipVal2) {
		return(1);
	}
	else if (*lipVal1 < *lipVal2) {
		return(-1);
	}

	return 0;
}

// 実行メイン
int
fMain(
	int piTNo					// <I> テスト番号 1～
)
{
	int i;
	char lc1Buf[1024], lc1Out[1024];

	// データ - 初期化
	memset(si1CCnt, 0, sizeof(si1CCnt));						// ろうそく数

	// 入力 - セット
#ifdef D_TEST
	sprintf(lc1Buf, ".\\Test\\T%d.txt", piTNo);
	szpFpI = fopen(lc1Buf, "r");
	sprintf(lc1Buf, ".\\Test\\A%d.txt", piTNo);
	szpFpA = fopen(lc1Buf, "r");
	siRes = 0;
#else
	szpFpI = stdin;
#endif

	// ろうそく数・着火数 - 取得
	int liCCnt, liFCnt;
	fgets(lc1Buf, sizeof(lc1Buf), szpFpI);
	sscanf(lc1Buf, "%d%d", &liCCnt, &liFCnt);

	// ろうそく - 取得
	int liVal;
	for (i = 0; i < liCCnt; i++) {
		fscanf(szpFpI, "%d", &liVal);

		if (liVal > 0) {								// １列目に追加
			si2Candle[0][si1CCnt[0]] = liVal;
			si1CCnt[0]++;
		}
		else if (liVal < 0) {							// ２列目に追加
			si2Candle[1][si1CCnt[1]] = -liVal;
			si1CCnt[1]++;
		}
		else {											// 着火数デクリメント
			liFCnt--;
		}
	}
	fgets(lc1Buf, sizeof(lc1Buf), szpFpI);

	// ２列目 - ソート
	if (si1CCnt[1] > 1) {
		qsort(si2Candle[1], si1CCnt[1], sizeof(int), fSortFnc);
	}

	// １列目の最大着火数
	int liCnt1;
	if (liFCnt < si1CCnt[0]) {
		liCnt1 = liFCnt;
	}
	else {
		liCnt1 = si1CCnt[0];
	}

	// 最小時間 - 算出
	int liMin = INT_MAX;
	for (i = liCnt1; i >= 0; i--) {

		// １列目の着火数
		int liVal1 = 0;
		if (i > 0) {
			liVal1 = si2Candle[0][i - 1];
		}

		// ２列目の着火数
		int liCnt2 = liFCnt - i;
		if (liCnt2 > si1CCnt[1]) {
			break;
		}
		int liVal2 = 0;
		if (liCnt2 > 0) {
			liVal2 = si2Candle[1][liCnt2 - 1];
		}

		// 短い距離を往復
		if (liVal1 < liVal2) {
			liVal1 *= 2;
		}
		else {
			liVal2 *= 2;
		}

		// 合計
		int liSum = liVal1 + liVal2;

		// 最小時間 - 更新
		if (liMin > liSum) {
			liMin = liSum;
		}
	}

	// 結果 - セット
	sprintf(lc1Out, "%d\n", liMin);

	// 結果 - 表示
#ifdef D_TEST
	fgets(lc1Buf, sizeof(lc1Buf), szpFpA);
	if (strcmp(lc1Buf, lc1Out)) {
		siRes = -1;
	}
#else
	printf("%s", lc1Out);
#endif

	// テストファイルクローズ
#ifdef D_TEST
	fclose(szpFpI);
	fclose(szpFpA);
#endif

	// テスト結果
#ifdef D_TEST
	if (siRes == 0) {
		printf("OK %d\n", piTNo);
	}
	else {
		printf("NG %d\n", piTNo);
	}
#endif

	return 0;
}

int
main()
{

#ifdef D_TEST
	int i;
	for (i = D_TEST_SNO; i <= D_TEST_ENO; i++) {
		fMain(i);
	}
#else
	fMain(0);
#endif

	return 0;
}