题目链接:传送门
大致题意:给一个长度为6的数组a ,一个长度为n的数组b,对于每一个b[j] ,必须选择任意一个a[i] 并产生一个差值 x=b[j]-a[i] ,问所有方案中 MIN(最大差值-最小差值),即最小化 最大差值-最小差值;
题目思路:预处理出所有的差值(6n个),并对其排序,枚举l (作为最小差值),维护r (作为最大差值),并且[l ,r ]之间恰好含有n个不同的b[i]产生的差值;
代码:

1 #include<bits/stdc++.h> 2 //#pragma GCC optimize(2) 3 using namespace std; 4 typedef long long LL; 5 typedef unsigned long long uLL; 6 typedef pair<int,int> pii; 7 typedef pair<LL,LL> pLL; 8 typedef pair<double,double> pdd; 9 const int N=1e5+5; 10 const int M=8e5+5; 11 const int inf=0x3f3f3f3f; 12 const LL mod=1e8+7; 13 const double eps=1e-8; 14 const long double pi=acos(-1.0L); 15 #define ls (i<<1) 16 #define rs (i<<1|1) 17 #define fi first 18 #define se second 19 #define pb push_back 20 #define eb emplace_back 21 #define mk make_pair 22 #define mem(a,b) memset(a,b,sizeof(a)) 23 LL read() 24 { 25 LL x=0,t=1; 26 char ch; 27 while(!isdigit(ch=getchar())) if(ch=='-') t=-1; 28 while(isdigit(ch)){ x=10*x+ch-'0'; ch=getchar(); } 29 return x*t; 30 31 } 32 int a[N],b[N],tot,cnt[N]; 33 pii c[N*6]; 34 int main() 35 { 36 for(int i=1;i<=6;i++) a[i]=read(); 37 int n=read(); 38 for(int i=1;i<=n;i++) b[i]=read(); 39 for(int i=1;i<=6;i++) 40 for(int j=1;j<=n;j++) c[++tot]=mk(b[j]-a[i],j); 41 sort(c+1,c+tot+1); 42 //for(int i=1;i<=tot;i++) printf("%d%c",c[i].fi,i==tot?' ': ' '); 43 int ans=inf,res=0; 44 for(int l=1,r=1;l<=tot;l++) 45 { 46 while(r<=tot&&res<n) 47 if(cnt[c[r++].se]++==0) res++; 48 49 if(res<n) break; 50 //printf("%d , %d ",l,r); 51 ans=min(ans,c[r-1].fi-c[l].fi); 52 if(cnt[c[l].se]--==1) res--; 53 } 54 printf("%d ",ans); 55 return 0; 56 }