Problem:
Score : 400 points

Problem Statement

We have N points in a two-dimensional plane.

The coordinates of the i-th point (1 \leq i \leq N) are (x_i,y_i).

Let us consider a rectangle whose sides are parallel to the coordinate axes that contains K or more of the N points in its interior.

Here, points on the sides of the rectangle are considered to be in the interior.

Find the minimum possible area of such a rectangle.

Constraints

2 \leq K \leq N \leq 50

-10^9 \leq x_i,y_i \leq 10^9 (1 \leq i \leq N)

x_i≠x_j (1 \leq i<j \leq N)

y_i≠y_j (1 \leq i<j \leq N)

All input values are integers. (Added at 21:50 JST)

Input

Input is given from Standard Input in the following format:

N K
x_1 y_1
:
x_{N} y_{N}

Output

Print the minimum possible area of a rectangle that satisfies the condition.

Sample Input 1

4 4
1 4
3 3
6 2
8 1

Sample Output 1

21

One rectangle that satisfies the condition with the minimum possible area has the following vertices: (1,1), (8,1), (1,4) and (8,4).

Its area is (8-1) × (4-1) = 21.

Sample Input 2

4 2
0 0
1 1
2 2
3 3

Sample Output 2

1

Sample Input 3

4 3
-1000000000 -1000000000
1000000000 1000000000
-999999999 999999999
999999999 -999999999

Sample Output 3

3999999996000000001

Watch out for integer overflows.

Solution in C (GCC 5.4.1) (judge verdict: Wrong Answer)

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

// 内部定数
#define D_VTX_MAX		50										// 最大座標数

// 内部構造体 - 頂点情報
typedef struct Vtx {
	int miX;													// 座標Ⅹ
	int miY;													// 座標Ｙ
} Vtx;

// 内部変数
static Vtx sz1Vtx[D_VTX_MAX];									// 頂点情報
static int siVCnt;												// 頂点情報数
static int siNCnt;												// 必要頂点数
static long long slMin;											// 最小面積

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

// ソート関数 - Ｘ座標昇順
int
fSortFncX(
	const void *pzpVal1			// <I> 値１
	, const void *pzpVal2		// <I> 値２
)
{
	Vtx *lzpVal1 = (Vtx *)pzpVal1;
	Vtx *lzpVal2 = (Vtx *)pzpVal2;

	// Ｘ座標昇順
	if (lzpVal1->miX > lzpVal2->miX) {
		return(1);
	}
	else if (lzpVal1->miX < lzpVal2->miX) {
		return(-1);
	}

	return 0;
}

// ソート関数 - int昇順
int
fSortFncI(
	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, j, k;
	char lc1Buf[1024], lc1Out[1024];

	// データ初期化
	slMin = LLONG_MAX;											// 最小面積

	// テストファイルオープン
#ifdef D_TEST
	sprintf(lc1Buf, ".\\Test\\T%d.txt", piTNo);
	szpFpT = fopen(lc1Buf, "r");
	sprintf(lc1Buf, ".\\Test\\A%d.txt", piTNo);
	szpFpA = fopen(lc1Buf, "r");
	siRes = 0;
#endif

	// 頂点情報数・必要頂点数取得
#ifdef D_TEST
	fgets(lc1Buf, sizeof(lc1Buf), szpFpT);
#else
	fgets(lc1Buf, sizeof(lc1Buf), stdin);
#endif
	sscanf(lc1Buf, "%d%d", &siVCnt, &siNCnt);

	// 頂点情報取得
	for (i = 0; i < siVCnt; i++) {
#ifdef D_TEST
		fgets(lc1Buf, sizeof(lc1Buf), szpFpT);
#else
		fgets(lc1Buf, sizeof(lc1Buf), stdin);
#endif
		sscanf(lc1Buf, "%d%d", &sz1Vtx[i].miX, &sz1Vtx[i].miY);
	}

	// ソート
	qsort(sz1Vtx, siVCnt, sizeof(Vtx), fSortFncX);

	// 算出
	for (i = 0; i < siVCnt - siNCnt + 1; i++) {
		for (j = i + siNCnt - 1; j < siVCnt; j++) {

			// Ｙ座標範囲
			int liYS, liYE;
			if (sz1Vtx[i].miY < sz1Vtx[j].miY) {
				liYS = sz1Vtx[i].miY;
				liYE = sz1Vtx[j].miY;
			}
			else {
				liYS = sz1Vtx[j].miY;
				liYE = sz1Vtx[i].miY;
			}

			// 内包頂点数
			int liCnt = j - i - 1;

			// 内包座標リスト
			int li1Y[D_VTX_MAX];
			for (k = 0; k < liCnt; k++) {
				li1Y[k] = sz1Vtx[i + 1 + k].miY;
			}
			qsort(li1Y, liCnt, sizeof(int), fSortFncI);

			// 不要内包頂点削除
			int liNoS = 0;
			int liNoE = liCnt - 1;
			while (liNoE - liNoS + 3 > siNCnt) {

				// 開始側
				int liLenS = liYS - li1Y[liNoS];				// 削除時の減少範囲
				if (liLenS > 0) {								// 削除可能
					if (liNoS < liCnt - 1) {						// 次の点あり
						if (liYS - li1Y[liNoS + 1] > 0) {				// 次の点も削除可能
							liLenS = li1Y[liNoS + 1] - li1Y[liNoS];			// 削除時の減少範囲
						}
					}
				}

				// 終了側
				int liLenE = li1Y[liNoE] - liYE;				// 削除時の減少範囲
				if (liLenE > 0) {								// 削除可能
					if (liNoE > 0) {								// 次の点あり
						if (li1Y[liNoE - 1] - liYE > 0) {				// 次の点も削除可能
							liLenE = li1Y[liNoE] - li1Y[liNoE - 1];			// 削除時の減少範囲
						}
					}
				}

				// 離れた内包頂点を削除
				if (liLenS > liLenE) {
					if (liLenS < 0) {								// なし
						break;
					}
					liNoS++;
				}
				else {
					if (liLenE < 0) {								// なし
						break;
					}
					liNoE--;
				}
			}

			// Ｙ座標範囲 - 更新
			if (liCnt > 0) {								// 内包頂点あり
				if (liYS > li1Y[liNoS]) {
					liYS = li1Y[liNoS];
				}
				if (liYE < li1Y[liNoE]) {
					liYE = li1Y[liNoE];
				}
			}

			// 面積
			long long llArea = (long long)(sz1Vtx[j].miX - sz1Vtx[i].miX) * (long long)(liYE - liYS);
			if (slMin > llArea) {
				slMin = llArea;
			}
		}
	}

	// 結果セット
	sprintf(lc1Out, "%lld\n", slMin);

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

	// テストファイルクローズ
#ifdef D_TEST
	fclose(szpFpT);
	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;
}