记录自己两个月前打CF以来第一个在时限内过掉的C题(好耶!)
简单二分
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define ull unsigned long long
ull a[105];
ull b[105];
ull n,h;
bool check(ull mid){
ull ans=0;
for (int i=1;i<=n;i++){
if (b[i]>=mid) ans+=mid;
else ans+=b[i];
}
if (ans>=h) return true;
else return false;
}
ll find(ull l,ull r){
if (l==r) return l;
if ((r-l)==1){
if (check(l)) return l;
else return r;
}
ull mid=(l+r)/2;
ull ans=0;
for (int i=1;i<=n;i++){
if (b[i]>=mid) ans+=mid;
else ans+=b[i];
}
if (ans==h) return mid;
if (ans>h) return find(l,mid);
if (ans<h) return find(mid,r);
}
void work(){
cin>>n;
cin>>h;
ull minn=1e9+1,maxn=0;//看数据范围,最大1e9
if (n==2) minn=1;//如果只有两次攻击,那么攻击间断区
//间就只有一个,所以最小认为是1,其实和后面的判定重合了
ull ans=0;
for (int i=1;i<=n;i++){
cin>>a[i];
if (i>=2){
b[i-1]=a[i]-a[i-1];//记录攻击间断区间的长度
if (minn>b[i-1]) minn=b[i-1];
if (maxn<b[i-1]) maxn=b[i-1];
ans+=b[i-1];
}
}
b[n]=maxn;
ans+=maxn;//先假设药效是maxn
if (ans==h){
cout<<maxn<<'\n';
return;
}
if (ans<h){
ans-=maxn;
cout<<h-ans<<'\n';
return;
}
if (check(minn)){
if (minn==1) {
cout<<1<<'\n';
return;
}
else {
cout<<find(1,minn)<<'\n';
return;
}
}
cout<<find(minn,maxn)<<'\n';
return;
}
int main(){
ios::sync_with_stdio(false);
int t;
cin>>t;
while (t--){
work();
}
return 0;
}