恭喜发现宝藏!搜索公众号【TechGuide】回复公司名,解锁更多新鲜好文和互联网大厂的笔经面经,题解自取
,目前已更新至华为、字节…
作者@TechGuide【全网同名】
第一道:小滴删数
题目描述
给你一个由正整数组成的集合,你需要从中删掉尽可能少的数使得该集合的众数出现次数不超过给定的参数k。
最终你需要输出至少需要删除几个数。
输入描述
第一行有两个正整数n,k (1≤k≤n≤100000 ),代表集合大小。
第二行有n 个正整数,范围在1 到1000000000之间,代表给出的集合。
5 1
1 3 2 2 1
输出描述
输出一个非负整数,即至少需要从集合中删除几个数才能使得集合中众数的出现次数不超过k。
2
思路
使用一个map来记录每个数出现的次数,然后遍历map。
对于每个数,如果它出现的次数大于等于k,则不需要处理,否则需要加上k与出现次数之差。
代码
Python版本
n, k = map(int, input().split())
a = list(map(int, input().split()))
mp = {}
for i in range(n+1):
mp[a[i]] = mp.get(a[i], 0) + 1
ans = 0
for x, y in mp.items():
ans += max(0, y - k)
print(ans)
# vx公众号关注TechGuide 实时题库 闪电速递。
Java版本
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int n = scanner.nextInt();
int k = scanner.nextInt();
int[] a = new int[n+1];
Map<Integer, Integer> mp = new HashMap<>();
for (int i = 0; i <= n; i++) {
a[i] = scanner.nextInt();
mp.put(a[i], mp.getOrDefault(a[i], 0) + 1);
}
int ans = 0;
for (Map.Entry<Integer, Integer> entry : mp.entrySet()) {
ans += Math.max(0, entry.getValue() - k);
}
System.out.println(ans);
}
}
// vx公众号关注TechGuide 实时题库 闪电速递
第二道:小明卖积木
题目描述
小明正在进行积木的分销。他共有N 个积木,他要将它们分装到M 个小包装内,每个小包装内至少有一个。
如果一个小包装内含x 个积木, 那么这个小包装将会被定价为x^2。小明想要控制一下价格, 不希望价格太贵或者太便宜。
他想要知道是否存在一种分装,使得分装后的M 个小包装定价之和恰好为P 。
如果有多种方案, 输出字典序最小的那一个。
对于两种不同方案a1 ,a2 ,…,aM 与b1 ,b2 ,…,bM
若对于1≤i≤t 的均有a_i=b_i ,且a_{t+1} ≤ b_{t+1} ,那么认为方案a 的字典序小于方案b。
注意:当t=0 时,没有合法的i存在,1≤i≤t 只是限制i的范围。
例如,对于M=3,N=4 的情况下,1,1,2 的字典序小于2,1,1 (对应t=0 的情况)、1,2,1 (对应t=1 的情况)。
输入描述
第一行三个正整数N,M,P ,对于所有数据,1≤M≤N≤12 ,0≤P≤10^9
4 3 6
输出描述
若不存在任何方案,输出-1, 否则输出M个数表示每个小包装内应分的的积木数量。
1 1 2
思路
dfs 来搜索当前的方案,每次搜索都会选择当前可行的数字,然后进入下一层递归。如果找到了可行方案,则调用 work 更新最优解。
check 用来判断当前方案是否更优。如果之前没找到最优解,则当前方案肯定更优。否则,我们需要比较当前方案和之前的最优解的大小,如果当前方案更优,则返回 True。work 用来更新当前的最优解。将当前方案赋给 tmp 数组,计算 tmp 数组的平方和,如果平方和等于 p,且当前方案更优,则更新最优解。
代码
Python版本
a = [0] * 200005
n, m, p = map(int, input().split())
num = [1] * 20
tmp = [0] * 20
ans = [0] * 20
f = False
def check(tmp):
global f
if f == False:
return True
for i in range(1, m+1):
if tmp[i] > ans[i]:
return False
elif tmp[i] < ans[i]:
return True
return True
def work():
global f
for i in range(1, m+1):
tmp[i] = num[i]
sum1 = 0
for i in range(1, m+1):
sum1 += tmp[i] * tmp[i]
if sum1 == p and check(tmp):
f = True
for i in range(1, m+1):
ans[i] = tmp[i]
def dfs(num1, dep):
if dep == m + 1:
if num1 == 0:
work()
return
for i in range(num1+1):
if num[dep] + i >= num[dep-1]:
num[dep] += i
dfs(num1-i, dep+1)
num[dep] -= i
for i in range(m+1):
num[i] = 1
n -= m
dfs(n, 1)
if not f:
print(-1)
else:
for i in range(1, m+1):
print(ans[i], end=' ')
# vx公众号关注TechGuide 实时题库 闪电速递。
Java版本
import java.util.*;
public class Main {
static int[] a = new int[200005];
static int n, m, p;
static int[] num = new int[20];
static int[] tmp = new int[20];
static int[] ans = new int[20];
static boolean f;
static boolean check(int[] tmp) {
if (!f)
return true;
for (int i = 1; i <= m; i++) {
if (tmp[i] > ans[i])
return false;
else if (tmp[i] < ans[i])
return true;
}
return true;
}
static void work() {
for (int i = 1; i <= m; i++)
tmp[i] = num[i];
int sum1 = 0;
for (int i = 1; i <= m; i++)
sum1 += tmp[i] * tmp[i];
if (sum1 == p && check(tmp)) {
f = true;
for (int i = 1; i <= m; i++)
ans[i] = tmp[i];
}
}
static void dfs(int num1, int dep) {
if (dep == m + 1) {
if (num1 == 0)
work();
return;
}
for (int i = 0; i <= num1; i++) {
if (num[dep] + i >= num[dep - 1]) {
num[dep] += i;
dfs(num1 - i, dep + 1);
num[dep] -= i;
}
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
n = sc.nextInt();
m = sc.nextInt();
p = sc.nextInt();
for (int i = 0; i <= m; i++)
num[i] = 1;
n -= m;
f = false;
dfs(n, 1);
if (!f)
System.out.println("-1");
else {
for (int i = 1; i <= m; i++)
System.out.print(ans[i] + " ");
}
sc.close();
}
}
// vx公众号关注TechGuide 实时题库 闪电速递