题号:NC21446
时间限制:C/C++ 1秒,其他语言2秒
空间限制:C/C++ 32768K,其他语言65536K
64bit IO Format: %lld
题目描述
太阳王葛温在结束了古龙的时代后,建立了亚诺尔隆德,然而数量众多的银骑士如何安置让他有些心烦。在某次用阳光枪打猎古龙之后,葛温想到了办法,他在亚诺尔隆德中开辟了一大片地方用来当作银骑士的居所,但是由于事务繁忙,他只好把工作安排给他的儿子——太阳长男手里,并嘱咐他尽快安排好,不然把他发配去天天猎古龙。你能帮帮太阳长男吗?
你可以把可安置区域看做一条一维坐标轴(从原点0开始到正无穷),在坐标值为整数的点上可以安排m个银骑士,但因为条件所限,可以安置银骑士的位置只有n个。由于银骑士们荣誉感太强,如果他们住的太近,就会展开决斗,试图割下对方的耳朵。所以你要让每个银骑士之间的最小距离尽可能地大来避免发生冲突。
输入描述:
第一行为一个正整数T,代表数据组数。对于每组数据,第一行有两个整数n和m(2<=n<=100000,2<=m<=n)。n代表可以安置区域的数量,m代表需要被安置的银骑士数量。接下来的n行中,每一行有一个非负整数ai(ai<=10^9),表示可以安置区域的位置。
输出描述:
输出一个整数,为把所有银骑士全部安排好后,他们之间的最小距离最大值。
示例1
输入
复制
1 5 3 1 2 8 4 9
输出
复制
3
说明
对于样例,你可以把3个银骑士分别安置在1、4、8的位置上,这样他们之间的最小距离为3。其他的安排方案,他们之间的最小距离都小于等于3,所以3是最大的最小距离
#include<iostream>
#include<string>
#include<cmath>
using namespace std;
const int mod=1e9+7;
typedef long long ll;
//void dfs(int a,int b){
// if(b==k) {
// ans++;
// return;
// }
// for(int i=a+1;i<=m*n;i++){
// int x=(i-1)/m+1;
// int y=(i-1)%m+1;
// if(s[x-1][y]==0&&s[x][y-1]==0){
// s[x][y]=1;
// dfs(i,b+1);
// s[x][y]=0;
// }
// }
//}
//bool is(long long x){
// if(x<=2) return true;
// for(long long i=2;i*i<x;i++){
// if(x%i==0) return false;
// }
// return true;
//}
//ll f(int x){
// if(x<2) return x;
// return (f(x/2)+f(x%2));
//}
//bool is(int x){
// int t=h/x;
// if(h%x!=0) t++;
// if(c-p*t<0){
// return false;
// }
// return true;
//}
//int sum;
//ll ff(ll n){
// if(n==1) return 1;
//
// return n*ff(n-1);
//}
//ll f(int n){
//
// while(n){
// sum+=n%10;
// n/=10;
// }
// if(n>=10){
// f(sum);
// }
// return sum;
//}
//const int MAXN = 305;
//const int INF = 0x3f3f3f3f;
//
//int love[MAXN][MAXN]; // 记录每个妹子和每个男生的好感度
//int ex_girl[MAXN]; // 每个妹子的期望值
//int ex_boy[MAXN]; // 每个男生的期望值
//bool vis_girl[MAXN]; // 记录每一轮匹配匹配过的女生
//bool vis_boy[MAXN]; // 记录每一轮匹配匹配过的男生
//int match[MAXN]; // 记录每个男生匹配到的妹子 如果没有则为-1
//int slack[MAXN]; // 记录每个汉子如果能被妹子倾心最少还需要多少期望值
//
//int N;
//
//
//bool dfs(int girl)
//{
// vis_girl[girl] = true;
//
// for (int boy = 0; boy < N; ++boy) {
//
// if (vis_boy[boy]) continue; // 每一轮匹配 每个男生只尝试一次
//
// int gap = ex_girl[girl] + ex_boy[boy] - love[girl][boy];
//
// if (gap == 0) { // 如果符合要求
// vis_boy[boy] = true;
// if (match[boy] == -1 || dfs( match[boy] )) { // 找到一个没有匹配的男生 或者该男生的妹子可以找到其他人
// match[boy] = girl;
// return true;
// }
// } else {
// slack[boy] = min(slack[boy], gap); // slack 可以理解为该男生要得到女生的倾心 还需多少期望值 取最小值 备胎的样子【捂脸
// }
// }
//
// return false;
//}
//
//int KM()
//{
// memset(match, -1, sizeof match); // 初始每个男生都没有匹配的女生
// memset(ex_boy, 0, sizeof ex_boy); // 初始每个男生的期望值为0
//
// // 每个女生的初始期望值是与她相连的男生最大的好感度
// for (int i = 0; i < N; ++i) {
// ex_girl[i] = love[i][0];
// for (int j = 1; j < N; ++j) {
// ex_girl[i] = max(ex_girl[i], love[i][j]);
// }
// }
//
// // 尝试为每一个女生解决归宿问题
// for (int i = 0; i < N; ++i) {
//
// fill(slack, slack + N, INF); // 因为要取最小值 初始化为无穷大
//
// while (1) {
// // 为每个女生解决归宿问题的方法是 :如果找不到就降低期望值,直到找到为止
//
// // 记录每轮匹配中男生女生是否被尝试匹配过
// memset(vis_girl, false, sizeof vis_girl);
// memset(vis_boy, false, sizeof vis_boy);
//
// if (dfs(i)) break; // 找到归宿 退出
//
// // 如果不能找到 就降低期望值
// // 最小可降低的期望值
// int d = INF;
// for (int j = 0; j < N; ++j)
// if (!vis_boy[j]) d = min(d, slack[j]);
//
// for (int j = 0; j < N; ++j) {
// // 所有访问过的女生降低期望值
// if (vis_girl[j]) ex_girl[j] -= d;
//
// // 所有访问过的男生增加期望值
// if (vis_boy[j]) ex_boy[j] += d;
// // 没有访问过的boy 因为girl们的期望值降低,距离得到女生倾心又进了一步!
// else slack[j] -= d;
// }
// }
// }
//
// // 匹配完成 求出所有配对的好感度的和
// int res = 0;
// for (int i = 0; i < N; ++i)
// res += love[ match[i] ][i];
//
// return res;
//}
int m,n;
int a[10005];
int check(int mid){
int res=1;
int p=a[1];
for(int i=2;i<=n;i++){
if(a[i]-p>=mid){
res++;
p=a[i];
}
}
return res>=m;
}
int main()
{
int t;
cin>>t;
while (t--) {
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
sort(a+1,a+n+1);
int l=0;
int r=a[n]-a[1];
while(l<=r){
int mid=(r+l)/2;
if(check(mid))
{
l=mid+1;
}
else{
r=mid-1;
}
}
cout<<l-1<<endl;
}
return 0;
}