codeforces 1077D Cutting Out 二分

Posted zmin

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了codeforces 1077D Cutting Out 二分相关的知识,希望对你有一定的参考价值。

题目:戳这里

题意:给n个数的数组,要求找k个数满足,这k个数在数组中出现的次数最多。

解题思路:k个数每个数出现次数都要最大化,可以想到二分下限,主要是正确的二分不好写。

附ac代码:

技术分享图片
 1 #include <bits/stdc++.h>
 2 typedef long long ll;
 3 const int maxn = 1e6+10;
 4 const ll inf = 1e18;
 5 using namespace std;
 6 int cnt[maxn];
 7 int s[maxn];
 8 int n, k;
 9 int ans[maxn];
10 int len = 0;
11 int check(int m,int n) {
12     int x = 0;
13     len = 0;
14     for(int i = 1; i <= n; ++i) {
15         x += cnt[s[i]] / m;
16         if(cnt[s[i]] / m > 0) {
17             ans[++len] = s[i];
18         }
19     }
20     if(x >= k) return 1;
21     else return 0;
22 }
23 int main(){
24 
25     scanf("%d %d", &n, &k);
26     for(int i = 1; i <= n; ++i) {
27         scanf("%d", &s[i]);
28         cnt[s[i]]++;
29     }
30 
31     int l = 1, r = n;
32     sort(s + 1, s + 1 + n);
33     n = unique(s + 1, s +1 + n) - s -1;
34     ll sum = 0;
35     while(l <= r) {
36         int m = (l + r) / 2;
37         int u = check(m, n);
38         if(u == 1) l = m + 1, sum = m;//如果u>1,则m本身一直满足条件
39         else r = m - 1;
40     }
41     int now = 0;
42     for(int i = 1; i <= n; ++i) {
43         for(int j = 1; j <= cnt[s[i]] / sum; ++j) {//注意除以的是sum,我就是这里忘改了所以最后怎么都没过。。
44             printf("%d ", s[i]);
45             ++now;
46             if(now == k) return 0;
47         }
48     }
49     return 0;
50 }
View Code

 

以上是关于codeforces 1077D Cutting Out 二分的主要内容,如果未能解决你的问题,请参考以下文章

CodeForces 998B Cutting(贪心)

Cutting Out -codeforce

Cutting Codeforces Round #493 (Div. 2)

Codeforces Round #521 (Div. 3) D. Cutting Out 二分+排序

@codeforces - 594E@ Cutting the Line

CodeForces 1118F2. Tree Cutting (Hard Version)