题意:
有一个大小为6的数组a以及一个大小为n的数组b,b中任意一个元素与a中所有元素差值个数为6个,询问:b中每个元素取一个差值,使差值最大值-差值最小值的值最小
注:
∀
i
,
j
,
b
j
>
a
i
\forall i, j,bj > ai
∀i,j,bj>ai
很像今年2020CCPC秦皇岛的一道题,也是同样做法
解题思路:
将所有差值排序,利用双指针,满足区间种类数为n个即统计答案
AC代码
#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
using namespace std;
const int maxn = 1e5 + 10;
int vis[maxn];
int n, cnt, a[7];
int b[maxn * 6];
struct P {
int val, ord;
} p[maxn * 6];
bool cmp(P A, P B) {
if (A.val != B.val) return A.val < B.val;
else return A.ord < B.ord;
}
int main() {
for (int i = 1; i <= 6; i++)
cin >> a[i];
cin >> n;
for (int i = 1; i <= n; i++) {
cin >> b[i];
for (int j = 1; j <= 6; j++)
p[++cnt].val = b[i] - a[j], p[cnt].ord = i;
}
sort (p + 1, p + cnt + 1, cmp);
int mmin = 0, mmax = inf, ans = inf;
int pos1 = 1, pos2 = 1, num = 0;
while (pos2 <= cnt) {
if (vis[p[pos2].ord] == 0) num++;
vis[p[pos2].ord]++;
while (num == n && pos1 <= pos2 && vis[p[pos1].ord]) {
//当区间个数为n,并且左指针小于等于右指针,并且此时区间内,左指针的种类数要存在,才能进入
ans = min(ans, p[pos2].val - p[pos1].val);//统计答案
vis[p[pos1].ord]--, pos1++;//移动左指针,因为已经从小到大排序,所以这样处理显然更优
if (vis[p[pos1 - 1].ord] == 0) num--;
//因为pos1已经加加,所以要-1,判断原本区间的左指针是否在之后区间还存在,不存在则num--
}
pos2++;
}
cout << ans << endl;
}
/*
1 4 100 10 30 5
6
101 104 105 110 130 200
1 1 2 2 3 3
7
13 4 11 12 11 13 12
*/