//二分查找+判定 (思想很经典)
#include <stdio.h>
#include <string.h>
typedef __int64 llong;
const int MAXN = 510;
llong book[MAXN];
bool use[MAXN];
int N, K;
llong Max(llong a, llong b){return a > b ? a : b;}
int check(llong L)
{
int i, cnt;
llong sum = 0;
i = N - 1;
//用来标记段数,对于不同的L值,都是先进行更新。
memset(use, 0, sizeof(use));
//段数
cnt = 1;
while (i >= 0)
{
//大于,则须在I处断开,即任何一段之和要小于L
if (sum + book[i] > L)
{
//标记此处要段开
use[i+1] = 1;
//段数加1
cnt++;
//开始新的一段
sum = book[i];
}
else
{
//小于,仍属于此段
sum += book[i];
}
i--;
}
return cnt;
}
void solve()
{
int i;
llong min, max, mid, cnt, sum;
min = 0;
sum = 0;
scanf("%d %d", &N, &K);
//二分的起始点为[最小的页数 ,页数之和],因为最大值一定在这之间
for (i = 0; i < N; i++)
{
scanf("%I64d", &book[i]);
sum += book[i];
min = Max(min, book[i]);
}
max = sum;
//二分查找
while (min < max)
{
mid = (min + max) / 2;
//如果以MID为最大值,而得到的段数小于等于K,说明MID值太大了
if (check(mid) <= K)
max = mid;
//否则MID值太小,使得段数大于K
else
min = mid + 1;
}
//求出以MAX为最大值所能够得到的段数。(从后至前,因为题目要求使得前面的任务越小越好)
cnt = check(max);
for (i = 1; i < N && cnt < K; i++)
{
//多余的段数全部用在最前面,使得前面的工人任务数是最优解中最少的
if (!use[i])
{
use[i] = true;
cnt++;
}
}
for (i = 0; i < N; i++)
{
printf("%I64d ", book[i]);
if (use[i+1])
printf("/ ");
}
printf("/n");
}
int main()
{
int t;
scanf("%d", &t);
while (t--)
solve();
return 0;
}