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

 

posted @ 2018-11-17 17:15  euzmin  阅读(301)  评论(0编辑  收藏  举报