这个题目我也解释不清,希望有人能在评论里帮忙补充解释
题意:Dmitry需要在m天内考n门试,已知每次考试的时间,Dmitry可以调整一次考试,问调整之后考试的最小间距
解法:二分答案和模拟都可以,我用的是二分,假设两次考试之间最小时间为len,我们在原先数组中寻找到一个比它小的点将其删掉,在检查新的数组,是否符合要求即可
#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N = 5e5 + 10;
typedef pair<int,int>PI;
int n,m;
vector<int>v;
vector<int>s;
bool sovle(int len,int p)
{
s=v;
//删点
s.erase(s.begin()+p);
bool st=0;
//检查
for(int i=1;i<s.size();i++)
{
if(s[i]-s[i-1]-1<len)return 0;
//如果存在区间可以容纳这个点
if(s[i]-s[i-1]-1>=(len*2)+1)st=1;
}
//判断可不可以放在最后
if(m-s.back()-1>=len)st=1;
return st;
}
bool check(int mi)
{
int t=-1;
//查找到一个len小的点
for(int i=1;i<v.size();i++)
{
if(v[i]-v[i-1]-1<mi)
{
t=i;
break;
}
}
//判断
if(t==-1)return 1;
if(t&&sovle(mi,t))return 1;
if(t&&sovle(mi,t-1))return 1;
return 0;
}
void sove() {
cin>>n>>m;
v.clear();
s.clear();
int a; v.push_back(0);
for(int i=0;i<n;i++)cin>>a,v.push_back(a);
int l=0,r=1e9;
while(l<r)
{
int mi=l+r+1>>1;
if(check(mi))l=mi;
else r=mi-1;
//cout<<l<<"????"<<r<<endl;;
}
cout<<l<<endl;
}
signed main() {
int t = 1;
cin >> t;
while (t--)sove();
}