2024华为OD机试题库-(A卷+B卷+C卷+D卷)-(JAVA、Python、C++)
2024华为OD机试题库-(C卷+D卷)-(JAVA、Python、C++)
目录
题目描述
幼儿园组织活动,老师布置了一个任务:
每个小朋友去了解与自己同一个小区的小朋友还有几个。
我们将这些数量汇总到数组 garden 中。
请根据这些小朋友给出的信息,计算班级小朋友至少来自几个小区?
输入描述
输入:garden[] = {2, 2, 3}
输出描述
输出:7
备注
garden 数组长度最大为 999
每个小区的小朋友数量最多 1000 人,也就是 garden[i] 的范围为 [0, 999]
用例1
输入
2 2 3
输出
7
说明
第一个小朋友反馈有两个小朋友和自己同一小区,即此小区有3个小朋友。
第二个小朋友反馈有两个小朋友和自己同一小区,即此小区有3个小朋友。
这两个小朋友,可能是同一小区的,且此小区的小朋友只有3个人。
第三个小区反馈还有3个小朋友与自己同一小区,则这些小朋友只能是另外一个小区的。这个小区有4个小朋友。
解题思路
该题的输出应该是至少有多少个小朋友,题目描述中让求小朋友来自多少小区描述有误。本题的解题思路是使用贪心算法,令小朋友的数量尽量少。比如,小朋友A和小朋友B都说有两个小朋友和自己同小区,那么就可以假设A和B在同一个小区,使小朋友数目尽可能少。但也不是所有说自己小区有相同数量其他小朋友的人都可以假设在同一小区,比如小朋友ABCD都说自己小区的其他小朋友数目为2,那么这个小区的小朋友数目最多为3,但已经出现了四个小朋友,所以至少来自两个小区。假设n个小朋友说自己小区有x个其他小朋友,那么进行小区合并后,至少小朋友的数目是:ceil(n/(x+1))*(x+1).
代码
c++
#include <bits/stdc++.h>
using namespace std;
int func(vector<int> vec) {
int res=0;
map<int,int> dict;
for(auto v:vec) {
dict[v]++;
}
for(auto d:dict) {
int cnt=d.second;//有key个小朋友来自相同小区的小区个数
res+=ceil((float)cnt/(d.first+1))*(d.first+1); //这些小朋友至少来自ceil(cnt/(d.first+1))个小区,每个小区(d.first+1)人
}
return res;
}
int main() {
int tmp;
vector<int> vec;
while(cin>>tmp) {
vec.push_back(tmp);
if(cin.get()=='\n') break;
}
cout<<func(vec)<<endl;
system("pause");
return 0;
}
Java
import java.util.Arrays;
import java.util.HashMap;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
try {
int[] nums = Arrays.stream(sc.nextLine().split(" ")).mapToInt(Integer::parseInt).toArray();
System.out.println(getResult(nums));
} catch (Exception e) {
System.out.println("0");
}
}
public static int getResult(int[] nums) {
HashMap<Integer, Integer> cnts = new HashMap<>();
for (int num : nums) {
cnts.put(num, cnts.getOrDefault(num, 0) + 1);
}
int ans = 0;
for (int key : cnts.keySet()) {
int total = key + 1;
ans += Math.ceil(cnts.get(key) * 1.0 / total) * total;
}
return ans;
}
}
Python
import math
vec=list(map(int,input().split()))
res=0 #至少有多少小朋友
map={} #存有k个其他小朋友的小区个数,相同其他小朋友个数的小区可以合并
for i in vec:
if i not in map:
map[i]=0
map[i]+=1
for k in map:
cnt=map[k] #有k+1个小朋友的小区个数
res+=math.ceil(cnt/(k+1))*(k+1) #小区进行合并,至少的小区个数*每个小区的人数
print(res)