华为机试三道编程题(2021-09-15)

通知:最新的秋招笔试编程题题目、思路以及参考代码已经全部整理好放在【TechGuide】了,私信公众号回复【华为】或者【百度】即可获得最实时的笔试题解啦!

通知:最新的秋招笔试编程题题目、思路以及参考代码已经全部整理好放在【TechGuide】了,私信公众号回复【华为】或者【百度】即可获得最实时的笔试题解啦!

通知:最新的秋招笔试编程题题目、思路以及参考代码已经全部整理好放在【TechGuide】了,私信公众号回复【华为】或者【百度】即可获得最实时的笔试题解啦!

通知:最新的秋招笔试编程题题目、思路以及参考代码已经全部整理好放在【TechGuide】了,私信公众号回复【华为】或者【百度】即可获得最实时的笔试题解啦!
在这里插入图片描述

【2021-09-04】美团秋招笔试五道编程题(附题目)
【2021-09-03】贝壳秋招笔试四道编程题(前三道ac)
【2021-09-01】阿里巴巴秋招笔试两道编程题
【2021-09-01】华为秋招机试三道编程题(附题目,后两题AC)
【2021-08-29】美团秋招笔试四道编程题
【2021-08-29】字节跳动秋招笔试四道编程题
【2021-08-26】腾讯音乐秋招笔试编程三道题
【2021-08-25】华为秋招机试三道编程题
【2021-08-23】阿里巴巴秋招笔试两道编程题
【2021-08-22】腾讯秋招笔试五道编程题
【2021-08-22】美团秋招笔试五道编程题(待更新)
【2021-08-21】网易秋招机试四道编程题(待更新)
【2021-08-14】荣耀秋招机试三道编程题(已更新)
【2021-08-18】华为秋招机试三道编程题(已更新)
【2021-08-18】阿里秋招笔试两道编程题
【2021-08-15】美团秋招笔试五道编程题(已更新)
【2021-08-12】携程秋招笔试三道编程题
【2021-08-11】华为秋招机试三道编程题(已更新)
【2021-08-09】阿里巴巴秋招笔试两道编程题
【2021-08-08】拼多多秋招笔试四道编程题
【2021-08-08】美团秋招笔试五道编程题
【2021-08-08】好未来秋招三道编程题
【2021-08-07】网易互娱秋招笔试三道编程题
【2021-08-04】华为秋招两道编程题

以下题目来自于口述,可能不准确,仅供参考,题解整理于牛客网,链接已附上,侵删。

第一道:最小覆盖半径

题目描述

类似于力扣475,题面如下:

冬季已经来临。 你的任务是设计一个有固定加热半径的供暖器向所有房屋供暖。

在加热器的加热半径范围内的每个房屋都可以获得供暖。

现在,给出位于一条水平线上的房屋 houses 和供暖器 heaters 的位置,请你找出并返回可以覆盖所有房屋的最小加热半径。

输入描述

houses = [1,2,3], heaters = [2]

输出描述
1

解释
仅在位置2上有一个供暖器。如果我们将加热半径设为1,那么所有房屋就都能得到供暖。

参考代码

二分枚举加热半径,根据在该半径下能加热的房屋数量来判断是否可行,然后移动左右边界使之相同即为答案。

CPP版本

class Solution {
public:
    int findRadius(vector<int>& houses, vector<int>& heaters) {
        int ans=0;
        sort(heaters.begin(),heaters.end());
        for(auto house:houses){
            int left=findLeft(house,heaters);
            int right=findRight(house,heaters);
            int mostClose=INT_MAX;
            //cout<<left<<right<<' '<<house<<endl;
            if(left==-1)mostClose=heaters[right]-house;
            else if(right==-1)mostClose=house-heaters[left];
            else mostClose=min(house-heaters[left],heaters[right]-house);
            ans=max(ans,mostClose);
        }
        return ans;
    }
    int findBig(int house,vector<int>&heaters){
        int n=heaters.size();
        int left=0,right=n-1;
        while(left<right){
            int mid=(left+right>>1)+1;
            //cout<<house<<' '<<left<<right<<mid<<' '<<heaters[mid]<<endl;
            if(heaters[mid]<=house)left=mid;
            else if(heaters[mid]>house)right=mid-1;
        }
        if(heaters[left]>house)return -1;
        return left;
    }
    int findSmall(int house,vector<int>&heaters){
        int n=heaters.size();
        int left=0,right=n-1;
        while(left<right){
            int mid=left+right>>1;
            if(heaters[mid]>=house)right=mid;
            else if(heaters[mid]<house)left=mid+1;
        }
        if(heaters[left]<house)return -1;
        return left;
    }
}
// 关注TechGuide! 大厂笔经面经闪电速递!

JAVA版本

class Solution {
    public int findRadius(int[] houses, int[] heaters) {
        //该法能成立的先决条件为两数组一定都要从小到大排好序
        Arrays.sort(heaters);
        Arrays.sort(houses);
        int l = 0 , r = Integer.MAX_VALUE;
        //开始二分枚举
        while(l < r){
            int mid = (l+r) >>> 1;
            //成立时,右界移动至中心
            if(Helper(houses , heaters , mid)){
                r = mid;
            //不成立时,左界移至中心+1
            //这样可以保证最后的跳出循环l一定为半径最小
            }else{
                l = mid+1; 
            }
        }
        return l;
    }
    public boolean Helper(int[] houses, int[] heaters, int len){
        int m = houses.length , n = heaters.length;
        int index = 0;
        for(int i = 0 ; i < n ; i++){
            long l = heaters[i]-len , r = heaters[i]+len;
            //计算能否完全覆盖房屋
            while(index < m && (long)houses[index] >= l && (long)houses[index] <= r){
                index++;
            }
            if(index == m) return true;
        }
        return false;
    }
}
// 关注TechGuide! 大厂笔经面经闪电速递!

第二道:数组对是否可以被整除(100%)

题目描述

类似力扣1497,题目如下:

有n个人参加某个项目比赛,每个人有两次机会,每个人参加项目后的得分x都被记录下来。如果成绩不达标,则会扣分,记得分可能为负数。所有人比赛完成后,得到2*n个积分,这些积分两两组合成n个积分对。有一个项目历史平均打分averageScore,现在将积分两两组合相加,希望所有积分对和都可以被平均得分averageScore整除。

若可以组成这样的积分对时,请输出组合方案,若无法组成这样的积分对,请输出0。积分对输出时,请先输出积分对中较大的数。

输入:
averageScore=5:
1 10 5 4 3 2 7 6 8 -1

输出:
10 5 8 7 6 4 3 2 1 -1

参考代码:

CPP版本

// 这里是判断是否可以即可,需要根据本题要求对输出做调整,但是思路一致,仅供参考
class Solution {
public:
    bool canArrange(vector<int>& arr, int k) {
        vector<int> mod(k);
        for (int num: arr) {
            ++mod[(num % k + k) % k];
        }
        for (int i = 1; i + i < k; ++i) {
            if (mod[i] != mod[k - i]) {
                return false;
            }
        }
        return mod[0] % 2 == 0;
    }
}
// 关注TechGuide! 大厂笔经面经闪电速递!

第三道:火车票销售的最大收益(100%)

题目描述

火车站推出一次火车票购买的优惠活动,即火车票可以分段售卖,连续2段八折,3段7折,给出乘客的起始和终点站,问如何售卖收益最大?

输入:
a,1,5
b,1,3
c,3,5

输出:
b c

参考代码

CPP版本

可以当作01背包用dp来做,对应的背包容量用四个比特位代表当前空闲的区间(1-2,2-3,3-4,4-5)。每个乘客会占用一部分区间,dp[mask][i]代表"只考虑第i个以后的乘客,且当前空闲状态是mask"时的最大收益。

#include <vector>
#include <string>
#include <iostream>
#include <sstream>
#include <utility>
using namespace std;

struct Guest {
    string name;
    int mask, pay;
    Guest(string name, int mask, int pay)
        : name(move(name)), mask(mask), pay(pay) {}
};

vector<string> solve(const vector<Guest>& guests)
{
    const int full = (1 << 4) - 1;
    vector<vector<int>> dp(full + 1, vector<int>(guests.size()));
    vector<vector<bool>> bookkeep(full + 1, vector<bool>(guests.size()));

    for (int bits = 1; bits <= full; bits++) {
        const auto& guest = guests.back();

        if ((guest.mask & bits) == guest.mask) {
            dp[bits][guests.size() - 1] = guest.pay;
            bookkeep[bits][guests.size() - 1] = true;
        }
    }

    for (int i = guests.size() - 2; i >= 0; i--) {
        const auto& guest = guests[i];

        for (int bits = 1; bits <= full; bits++) {
            dp[bits][i] = dp[bits][i + 1];
            if ((guest.mask & bits) != guest.mask) {
                continue;
            }
            if (dp[bits][i] <= dp[bits & ~guest.mask][i + 1] + guest.pay) {
                dp[bits][i] = dp[bits & ~guest.mask][i + 1] + guest.pay;
                bookkeep[bits][i] = true;
            }
        }
    }

    vector<string> result;
    int bits = full;
    for (int i = 0; i < guests.size(); i++) {
        const auto& guest = guests[i];

        if (bookkeep[bits][i]) {
            result.push_back(guest.name);
            bits &= ~guest.mask;
        }
    }
    return result;
}

int main()
{
    string line;
    vector<Guest> guests;

    while (cin >> line) {
        stringstream ss(line);
        string name, _from, _to;
        const int cost[5] = {
            0, 100, 180, 240, 280,
        };

        getline(ss, name, ',');
        getline(ss, _from, ',');
        getline(ss, _to, ',');

        int from = atoi(_from.c_str()) - 1, to = atoi(_to.c_str()) - 1;
        guests.emplace_back(name, (1 << to) - (1 << from), cost[to - from]);
    }

    auto result = solve(guests);
    for (int i = 0; i < result.size() - 1; i++) {
        cout << result[i] << ' ';
    }
    cout << result.back() << endl;

    return 0;
}
// 关注TechGuide! 大厂笔经面经闪电速递!

JAVA版本

import java.util.*;
public class HJ003{
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        LinkedList<Client> clients = new LinkedList<>();
        while(sc.hasNext()) {
         clients.add(getClient(sc.next()));
        }
        permute(clients);   //暴力求解出所有可能的客户组合,存放到结果集res
        int maxPos=0;       //记录最大收益位置
        int maxP =0;        //记录最大收益
        for(int i=0;i<res.size();i++) {
         int maxVal = 0;
   for(int j=0;j<res.get(i).size();j++) {
    maxVal += res.get(i).get(j).printPrice();
   }
   if(maxP<maxVal) {
    maxP=maxVal;
    maxPos=i;
   }
  }
        for(int i=0;i<res.get(maxPos).size();i++) {
         //输出最大收益组合
         System.out.print(res.get(maxPos).get(i).printName()+" ");
        }
    }
    //根据输入的每一行解析出客户信息,生成一个客户对象
    public static Client getClient(String str) {
     String[] arr = str.split(",");
     String name = arr[0];
     int start = Integer.parseInt(arr[1]);
     int end = Integer.parseInt(arr[2]);
     return new Client(name,start,end);
    }
    //存放所有合理方案
    static List<List<Client>> res = new LinkedList<>();
    //存放一个方案里所有客户
    static List<Client> list = new LinkedList<>();
    public static List<List<Client>> permute(LinkedList<Client> clients){
     helper(clients, 1);
     return res;
    }
    public static void helper(LinkedList<Client> clients, int end) {
     //触发结束条件
     if(end==5) {
      res.add(new LinkedList<Client>(list));
      return;
     }
     for(int i=0;i<clients.size();i++) {
      //排除不合理选择
      if(clients.get(i).printStart()!=end) {
       continue;
      }
      //做出选择
      list.add(clients.get(i));
      //进入下一层决策树
      helper(clients, clients.get(i).printEnd());
      //取消选择
      list.remove(list.size()-1);
     }
    }
}
//新建一个客户类,由客户的名种子,始发站,终点站构成一个客户,包含可以输出客户信息的方法
class Client{
 String name;
 int start;
 int end;

 public Client(String name, int start, int end) {
  this.name=name;
  this.start=start;
  this.end=end;
 }
 public String printName() {
  return this.name;
 }
 public int printStart() {
  return this.start;
 }
 public int printEnd() {
  return this.end;
 }
 public int printDistance() {
  return this.end-this.start;
 }
 public int printPrice() {
  return (int)((1-((double)(this.end-this.start-1))/10)*(this.end-this.start)*100);
 }
}
// 关注TechGuide! 大厂笔经面经闪电速递!

最新的秋招笔试编程题题目、思路以及参考代码已经全部整理好放在【TechGuide】了,私信公众号回复【华为】或者【百度】即可获得最实时的笔试题解啦!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值