cf1393c

题意大概是给我们一串数,问我们任意排列中相邻两个相同数的最小距离。

因为是CF的C题,而且这题面看完之后感觉就很贪心,所以我们开始构造一种贪心方案。

不难发现,要让相同数之间的距离更大,显然要把出现次数多的数往里面塞。

那么我们二分一下答案,对于每一次判断,我们使用优先队列维护一下,每次放进去出现次数最多的k个即可。

下附代码:

 1 #include<cstdio>
 2 #include<iostream>
 3 #include<algorithm>
 4 #include<queue>
 5 using namespace std;
 6 int cnt[100005],res[100005],c[100005],n;
 7 priority_queue<pair<int,int> > q;
 8 struct node{
 9     int t,num;
10 }a[100005];
11 bool cmp(node x,node y){
12     return x.t>y.t;
13 }
14 bool judge(int x){
15     for (int i=1; i<=n; i++) c[i]=cnt[i];
16     for (int i=1; i<=n; i++){
17         if (cnt[i]!=0){
18             q.push({cnt[i],i});
19         }
20     }
21     for (int i=1; i<=n; i++){
22         if (i-x-1>=1 && c[res[i-x-1]]) q.push({c[res[i-x-1]],res[i-x-1]});
23         if (q.empty()) return 0;
24         res[i]=q.top().second,c[res[i]]--,q.pop();
25     }
26     return 1;
27 }
28 int erfen(){
29     int l=0,r=n;
30     while(l<r){
31         int mid=(l+r+1)>>1;
32         if (judge(mid))  l=mid;
33         else  r=mid-1;
34     }
35     return l;
36 }
37 int main(){
38     int T;
39     scanf("%d",&T);
40     while (T--){
41         scanf("%d",&n);
42         for (int i=1; i<=n; i++) cnt[i]=0;
43         for (int i=1; i<=n; i++){
44             int x;
45             scanf("%d",&x);
46             cnt[x]++;
47         }
48         printf("%d
",erfen());
49     }
50     return 0;
51 }
View Code
原文地址:https://www.cnblogs.com/i-caigou-TT/p/13871312.html