cf 1413C (贪心排序+双指针)

题目链接:传送门

大致题意:给一个长度为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?'\n': ' ');
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\n",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\n",ans);
55     return 0;
56 }
View Code

 

posted @ 2020-10-27 15:42  DeepJay  阅读(115)  评论(0编辑  收藏  举报