Cutting Out
Explicación
Usamos búsqueda binaria para determinar la máxima cantidad de veces que se puede recortar el subarreglo del arreglo original. Una vez calculado, construimos el arreglo resultante incluyendo elementos en proporción a sus contribuciones.
Implementación
Complejidad temporal:
#include <iostream>
#include <vector>
const int MAX_N = 200000;
int main() {
int n, k;
std::cin >> n >> k;
std::vector<int> freq(MAX_N + 1);
for (int i = 0; i < n; i++) {
int x;
std::cin >> x;
freq[x] += 1;
}
auto can = [&](int x) -> bool {
int ele_num = 0;
for (int i = 1; i <= MAX_N; i++) { ele_num += freq[i] / x; }
return ele_num >= k;
};
int lo = 0;
int hi = n;
while (lo < hi) {
int mid = (lo + hi + 1) / 2;
if (can(mid)) {
lo = mid;
} else {
hi = mid - 1;
}
}
std::vector<int> res;
for (int i = 1; i <= MAX_N; i++) {
for (int j = 0; j < freq[i] / lo; j++) { res.push_back(i); }
}
for (int i = 0; i < k; i++) { std::cout << res[i] << " \n"[i == k - 1]; }
}import java.io.*;
import java.util.*;
public class CuttingOut {
private final static int MAX_N = 200000;
public static void main(String[] args) {
Kattio io = new Kattio();
int n = io.nextInt();
int k = io.nextInt();
int[] freq = new int[MAX_N + 1];
for (int i = 0; i < n; i++) {
int x = io.nextInt();
freq[x] += 1;
}
int lo = 0;
int hi = n;
while (lo < hi) {
int mid = (lo + hi + 1) / 2;
if (can(freq, mid, k)) {
lo = mid;
} else {
hi = mid - 1;
}
}
List<Integer> res = new ArrayList<>();
for (int i = 1; i <= MAX_N; i++) {
for (int j = 0; j < freq[i] / lo; j++) { res.add(i); }
}
for (int i = 0; i < k; i++) { io.print(res.get(i) + " "); }
io.close();
}
private static boolean can(int[] freq, int x, int k) {
int eleNum = 0;
for (int i = 1; i <= MAX_N; i++) { eleNum += freq[i] / x; }
return eleNum >= k;
}
// CodeSnip{Kattio}
}MAX_N = 200000
freq = [0] * (MAX_N + 1)
n, k = map(int, input().split())
for x in input().split():
freq[int(x)] += 1
def can(x: int) -> bool:
ele_num = 0
for i in range(1, MAX_N + 1):
ele_num += freq[i] // x
return ele_num >= k
lo = 0
hi = n
while lo < hi:
mid = (lo + hi + 1) // 2
if can(mid):
lo = mid
else:
hi = mid - 1
res = []
for i in range(1, MAX_N + 1):
for j in range(0, freq[i] // lo):
res.append(i)
print(*res[:k])