题意:
给定数组a(长度为6)然后给定长度为n的数组b,然后把bi-a(1−6)中任意一个,使得处理后的b数组跨度(最大值减最小值)最小。
题解:
显然对于每一个 bi,其最终取值有六种。我们考虑一开始先将所有取值中最小的全部拿出来,放到一个小根堆中,并且维护其最大值。
令最大值为 mx,最小值为 mn,则目前的答案为 ans=mx−mn。
然后我们考虑把目前的所有数中最小的拿出来,让后找到对应 bi 中的其他取值中排名比它大 1 的那个,然后重新放回堆中,更新答案。显然,我们这种做法可以使得我们所选的数尽可能的集中,所以可以得到最优解。
AC代码:
#include<bits/stdc++.h>
using namespace std;
using i64=long long;
const int N=1e6+10;
i64 a[N],b[N],c[N];
struct node{
i64 x,pos;
friend bool operator<(node a,node b) {
return a.x>b.x;
}
};
priority_queue<node>q;
const i64 mod=1e9+7;
void solve(){
for(int i=1;i<=6;i++){
cin>>a[i];
}
sort(a+1,a+7);
reverse(a+1,a+7);
i64 n;
cin>>n;
i64 maxl=0;
for(int i=1;i<=n;i++){
cin>>b[i];
c[i]=1;
q.push(node{abs(b[i]-a[1]),i});
maxl=max(maxl,b[i]-a[1]);
}
i64 ans=1e18;
while(!q.empty()){
node l=q.top();
q.pop();
ans=min(ans,maxl-l.x);
c[l.pos]++;
if(c[l.pos]>6){
cout<<ans<<"\n";
return ;
}
l.x=b[l.pos]-a[c[l.pos]];
q.push(l);
maxl=max(maxl,b[l.pos]-a[c[l.pos]]);
}
}
signed main(){
ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
int t;
t=1;
while(t--){
solve();
}
}