题意:
先给出一个长度为6的数组 a a a ,再给出一个长度为 n n n的数组 b b b ,求 b b b 数组的每个元素减去 a a a 数组中任意一个元素后,最后的数组 b b b 中最大值与最小值之差最小是多少?
题解:
对每个元素都先减去这6个数,用 p a i r pair pair存,第一位存减去后的值,第二位存这个元素的下标,然后对 p a i r pair pair 按照第一位排序。
用两个双指针遍历 p a i r pair pair , p o s 1 pos1 pos1 表示遍历到的左端点, p o s 2 pos2 pos2表示右端点 ,如果当前区间这 n n n个数都有,那么直接计算答案,并且 p o s 1 + + pos1++ pos1++ ,直到不满足条件,然后再 p o s 2 + + pos2++ pos2++
代码:
#pragma GCC diagnostic error "-std=c++11"
#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
#include<stack>
#include<set>
#include<ctime>
#define iss ios::sync_with_stdio(false)
using namespace std;
typedef unsigned long long ull;
typedef long long ll;
typedef pair<int,int> pii;
const int mod=1e9+7;
const int MAXN=2e5+5;
const int inf=0x3f3f3f3f;
pii p[MAXN*4];
int a[10];
int b[MAXN];
int vis[MAXN];
int main()
{
for(int i=1;i<=6;i++) cin>>a[i];
sort(a+1,a+1+6);
int n;
cin>>n;
int tot=0;
for(int i=1;i<=n;i++)
{
cin>>b[i];
for(int j=1;j<=6;j++)
{
p[++tot].first=b[i]-a[j];
p[tot].second=i;
}
}
int ans=2e9;
sort(p+1,p+1+tot);
int pos1=1,pos2=1;
int cnt=0;
while(pos2<=tot)
{
if(!vis[p[pos2].second]) cnt++;
vis[p[pos2].second]++;
while(cnt==n&&pos1<=pos2)
{
ans=min(ans,p[pos2].first-p[pos1].first);
vis[p[pos1].second]--;
if(!vis[p[pos1].second]) cnt--;
pos1++;
}
pos2++;
}
printf("%d\n",ans);
}