2024华为OD机试真题-小朋友来自多少小区-(C++/Java/Python)-C卷D卷-100分

2024华为OD机试题库-(A卷+B卷+C卷+D卷)-(JAVA、Python、C++)

2024华为OD机试题库-(C卷+D卷)-(JAVA、Python、C++)

目录

题目描述

输入描述

输出描述

用例1

解题思路

代码

c++

Java 

Python 


题目描述

幼儿园组织活动,老师布置了一个任务:

每个小朋友去了解与自己同一个小区的小朋友还有几个。

我们将这些数量汇总到数组 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)

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
题目描述: 给定一个字符串 s ,请你找出其中最长的不含重复字符的子串长度。 示例: 输入: "abcabcbb" 输出: 3 解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。 输入: "bbbbb" 输出: 1 解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。 思路析: 用一个 hash 表存储每个字符最后一次出现的位置。遍历字符串,记录当前子串的起始位置 start 和当前位置 i,当遇到重复字符时,更新 start 的位置。最后更新最长子串的长度。 代码实现: Python: class Solution(object): def lengthOfLongestSubstring(self, s): """ :type s: str :rtype: int """ hash_map = {} res = 0 start = 0 for i in range(len(s)): if s[i] in hash_map and hash_map[s[i]] >= start: start = hash_map[s[i]] + 1 hash_map[s[i]] = i res = max(res, i - start + 1) return res Java: class Solution { public int lengthOfLongestSubstring(String s) { int[] hash_map = new int[256]; int res = 0; int start = 0; for (int i = 0; i < s.length(); i++) { char c = s.charAt(i); if (hash_map[c] >= start) { start = hash_map[c] + 1; } hash_map[c] = i; res = Math.max(res, i - start + 1); } return res; } } C++: class Solution { public: int lengthOfLongestSubstring(string s) { vector<int> hash_map(256, -1); int res = 0; int start = 0; for (int i = 0; i < s.size(); i++) { char c = s[i]; if (hash_map[c] >= start) { start = hash_map[c] + 1; } hash_map[c] = i; res = max(res, i - start + 1); } return res; } }; 总结: 这道题考察了字符串的基础操作和 hash 表的使用。通过本题的练习,可以在实际开发中更加熟练地使用 hash 表,提高代码效率和可读性。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

2024剑指offer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值