10.25 Codeforces Round #679 (Div. 2) C. Perform Easily (双指针)

题意:

有一个大小为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

*/
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值