2024年华为9月4日秋招笔试真题题解

news2025/1/12 17:16:43

2024年华为0904秋招笔试真题

    • 二叉树消消乐
    • 好友推荐系统
    • 维修工
      • 力扣上类似的题--K站中转内最便宜的航班

二叉树消消乐

题目描述

给定原始二叉树和参照二叉树(输入的二叉树均为满二叉树,二叉树节点的值范围为[1,1000],二叉树的深度不超过1000),现对原始二叉树和参照二叉树中相同层级目值相同的节点进行消除、消除规则为原始叉树和参照二叉树中存在多个值相同的节点只能消除等数量的、消除后的节点变为无效节点,请按节点值出现频率从高到低输出消除后原始二叉树中有效节点的值(如果原始二叉树消除后没有有效节点返回0)。

输入描述

原始二叉树中的节点个数
原始二叉树
参照二叉树中的节点个数
参照二叉树

输出描述

原始二叉树中有效节点的值,按出现频率从高到低排序(相同频率的值按大小排序),相同频率的值按降序排列。

用例输入

7
1 3 3 3 4 5 6
3
2 3 4

用例输出

36541

样例1解释:
原始二叉树A消除参照二叉树B中的重复元素后,有效节点剩余2个3,1个6,1个5,1个4,1个1,3出现的频率2,6、5、4、1出现的频率为1,按值从大到小排序、所以排序结果为36541。

求解思路

注意审题,题目明确指出这是一个满二叉树,因此我们不需要真的去构建一个二叉树,只需要利用满二叉树的性质去进行模拟求解就行。

需要注意的是,华为的命题人在写题面时候不够严谨,题面说二叉树的深度不超过1000,这显然是不现实的,毕竟这是满二叉树,如果深度达到几十上百的话,二叉树的节点数直接2的几百次方,显然这么大的数据哪怕O(n)的时间复杂度也过不了。因此只需要按照节点数为1e5的规模来设计算法即可。

#include<bits/stdc++.h>
using namespace std;
const int maxn = 100001;
int n, m;
int origin[maxn], refer[maxn];
vector<int>sum(maxn, 0);

void dfs(int depth) {
    int start = pow(2, depth - 1), end = start + pow(2, depth - 1);
    if(start > n || start > m) return;
    map<int, int>mp1, mp2;
    for(int i = start; i < end; i++) {
        mp1[origin[i]]++;
        mp2[refer[i]]++;
    }
    for(auto i : mp1) {
        if(mp2[i.first] > i.second) sum[i.first] -= i.second;
        else sum[i.first] -= mp2[i.first];
        // cout << i.first << " " << sum[i.first] << endl;
    }
    dfs(depth + 1);
}

bool cmp(pair<int, int>a, pair<int, int> b) {
    if(a.second != b.second) return a.second > b.second;
    return a.first > b.first;
}

int main() {
    scanf("%d", &n);
    for(int i = 1; i <= n; i++) {
        scanf("%d", &origin[i]);
        sum[origin[i]]++;
    }
    scanf("%d", &m);
    for(int i = 1; i <= m; i++) scanf("%d", &refer[i]);

    dfs(1);

    // for(int i = 1; i <= n; i++) cout << sum[origin[i]] << " ";
    // cout << endl;

    vector<pair<int, int>>v;
    set<int>s;
    for(int i = 1; i <= n; i++) s.insert(origin[i]);
    for(auto i : s) v.push_back(make_pair(i, sum[i]));

    // for(auto i : s) cout << i << " " << sum[i] << " " << endl;

    sort(v.begin(), v.end(), cmp);
    bool flag = false;
    for(auto i : v) {
        if(i.second != 0) {
            flag = true;
            printf("%d", i.first);
        } 
        else break;
    }
    if(!flag) printf("0");

    return 0;
}
/*
15
5 8 8 8 7 7 7 6 6 9 9 7 7 5 6
7
5 6 6 7 7 8 8
*/

好友推荐系统

题目描述

你正在为一个社交网络平台开发好友推荐功能。

平台上有N个用户(每个用户使用1到N的整数编号),同时系统中维护了用户之间的好友关系。

为了推荐新朋友,平台决定采用“共同好友数量"作为衡量两个用户之间相似度的标准。

系统根据输入用户编号K,输出与此用户K相似度最高的前L个用户ID来推荐给用户K。

相似度定义:两个用户非好友,两个用户的相似度为拥有的共同好友数(例如用户A和用户B,只有共同好友C和D,相似度=2)

输入描述

第一行包含四个整数 N,M 、K和L,分别表示用户的数量(N),好友记录条数(M)、查询的用户编号(K)和推荐的好友数量(L)。接下来 M 行,每行包含两个整数编号X和Y,表示编号为X和Y用户是好友。

  1. 输入格式都是标准的,无需考虑输出异常场景(不会包含用户和自己是好友的输入,例如11)

  2. 用户数不超过1024,用户编码最大1024

  3. 好友记录数不超过10240

输出描述

根据输入K和L,输出和用户K相似度最高的L个用户编码。

  1. 输出相似度最高的前L个用户编码,按照相似度从高到低排序

  2. 如果有相似度相同的可能好友,按照用户编号从小到大排序

  3. 如果推荐的好友个效不足L个,则推荐与用户K无无共同好友关系的用户(陌生人)作为可能好友,如果推荐仍不满足L个用户,剩余推荐用户编码使用0来占位

用例输入

6 7 3 2
1 2
1 3
2 3
3 4
3 5
4 5
5 6

用例输出

6 0

输入包含了6个用户,7条好友记录,给用户ID编号为3的用户推荐2个好友。

输出只有编号为6的用户可能是编号3用户的可能好友;

尝试推荐与编号3用户无共同好友的其他用户,由于除编号为6的用户之外,其他用户和编号3用户都是好友,所以找不到陌生人作为推荐的第二个用户;

推荐结果不足2个用户,所以推荐的第二个用户编码使用0来占位补足。

求解思路

我们首先可以利用哈希表构建用户之间的好友关系,方便在O(1)的时间复杂度内查找两个用户之间是否是好友关系

然后排序遍历就可以得到推荐列表了

#include<bits/stdc++.h>
using namespace std;
bool cmp(pair<int, int> a, pair<int, int> b) {
    if(a.second != b.second) return a.second > b.second;
    return a.first < b.first;
}
int main() {
    int N, M, K, L;
    scanf("%d %d %d %d", &N, &M, &K, &L);
    int x, y;
    int isf[1025][1025] = {0};
    for(int i = 0; i < M; i++) {
        scanf("%d%d", &x, &y);
        isf[x][y] = isf[y][x] = 1;
    }

    vector < pair<int, int> > sim;

    for(int i = 1; i <= N; i++) {
        if(i == K) continue;
        if(isf[K][i] != 1) {
            int cnt = 0;
            for(int j = 1; j <= N; j++) {
                if(i == j) continue;
                if(isf[K][j] == 1 && isf[i][j] == 1) cnt++;
            }
            sim.push_back(make_pair(i, cnt));
        }
    }

    sort(sim.begin(), sim.end(), cmp);
    int sum = 0;
    for(auto i : sim) {
        printf("%d ", i.first);
        sum++;
    }
    if(sum < L) {
        for(int i = sum; i < L; i++) printf("0 ");
    }

    return 0;
}

维修工

题目描述

维修工要给n个客户更换设备,为每个用户更换一个设备。维修工背包内最多装k个设备,如果背包里有设备可以直接前往下一个客户更换或回公司补充设备,没有则需要回公司取设备。这些客户有优先级,维修工需要按照优先级给客户更换设备,优先级level用数字表示,数字小的优先级高。维修工从公司出发,给n个客户更换设备,最后再返回公司。请计算维修工完成这项工作所需要经历的最短总距离是多少。维修工可以走斜线。

输入描述

第一行两个正整数 n,k(1≤k≤n≤2000),表示客户数和维修工背包容量。
第二行两个正整数 x,y ,用空格分隔(1 ≤ x , y ≤ 10^6),表示公司的坐标
接下来n行每行三个正整数 x i x_i xi, y i y_i yi, l e v e l i level_i leveli,用空格分隔(1≤ x i x_i xi, y i y_i yi≤10^6,1≤ l e v e l i level_i leveli<=n)。
( x i x_i xi, y i y_i yi)表示第i个客户的位置坐标, l e v e l i level_i leveli表示第 i i i个客户的优先级,保证所有客户优先级不同,客户和公司坐标不会重叠。

输出描述

输出最短总距离,结果四舍五入并保留一位小数,例如:9.0。

用例输入

3 2
1 1
3 1 1
1 2 2
3 2 3

用例输出

9.2

样例1解释:

从(1,1)->(3,1)->(1,1)->(1,2)->(3,2)->(1,1) = 2+2+1+2+√5 = 9.236

求解思路

题目的意思是维修工在维修完一家客户后,就会废掉背包内的一个设备(题面没讲清楚,一开始理解了好久背包内有设备为什么需要回公司取)。

因为本题规定了客户的优先级,因此我们首先将客户按照优先级进行排序。

接下来,我们可以按照记忆化搜索的方法,决定维修完当前客户后,到底回公司取设备再前往下一家客户还是直接去下一家客户维修。

我们采用memo数组记录每次的结果

memo[i + 1][k - 1] 表示回公司取完设备再前往下一家客户维修

memo[i + 1][j - 1] 表示背包内还有设备,直接前往下一家客户维修

#include<bits/stdc++.h>
using namespace std;

double cal_dis(int x1, int y1, int x2, int y2) {
    return (double)sqrt(pow(x1 - x2, 2) + pow(y1 - y2, 2));
}

const int maxn = 2001;
int n, k, cx, cy;

struct customer
{
    int x, y, level;
    bool operator < (const customer& other) const { 
        return level < other.level; 
    }
}p[maxn];

/*
记忆化搜索,假设memo[i][j]表示维修完第i个客户,并且背包中还剩下j个设备。
*/
vector <vector<double>> memo(maxn, vector<double>(maxn, 0)); 

double dfs(int i, int j) {
    if(memo[i][j] > 0) return memo[i][j];
    double dis = cal_dis(p[i].x, p[i].y, cx, cy);
    double ans = 99999999999.0;
    if(i < n - 1) {
        ans = min(ans, dfs(i + 1, k - 1) + dis + cal_dis(p[i + 1]. x, p[i + 1].y, cx, cy));
        // cout << dis + cal_dis(p[i + 1]. x, p[i + 1].y, cx, cy) << endl;
        if(j > 0) {
            ans = min(ans, dfs(i + 1, j - 1) + cal_dis(p[i + 1].x, p[i + 1].y, p[i].x, p[i].y));
            // cout <<  cal_dis(p[i + 1].x, p[i + 1].y, p[i].x, p[i].y) << endl;
        }
    } else { // 如果是最后一家,则修完直接回公司
        ans = dis;
    }
    return memo[i][j] = ans;
}

int main() {
    scanf("%d%d", &n, &k);
    scanf("%d%d", &cx, &cy);
    for(int i = 0; i < n; i++) scanf("%d%d%d", &p[i].x, &p[i].y, &p[i].level);
    sort(p, p + n);

    dfs(0, k);

    double ans = dfs(0, k - 1) + cal_dis(p[0].x, p[0].y, cx, cy);
    printf("%.1f", ans);

    return 0;
}

维修工这个题是通过记忆化搜索求解最短路径的问题,想起之前在力扣上面刷到一个类似的题目,K站中转内最便宜的航班

题目链接

力扣上类似的题–K站中转内最便宜的航班

题目描述

n 个城市通过一些航班连接。给你一个数组 flights ,其中 flights[i] = [fromi, toi, pricei] ,表示该航班都从城市 fromi 开始,以价格 pricei 抵达 toi

现在给定所有的城市和航班,以及出发城市 src 和目的地 dst,你的任务是找到出一条最多经过 k 站中转的路线,使得从 srcdst价格最便宜 ,并返回该价格。 如果不存在这样的路线,则输出 -1

image-20240912141710328

image-20240912141914144

求解思路

和维修工一样,我们只需要利用记忆化搜索去寻找到第k个城市所需要的最少花费即可,注意k次中转的限制。

class Solution {
public:
    const int INF = 99999999;
    /*
    dp[i][j] 表示起点到城市i到达第j个城市的最少花费
    */
    int findCheapestPrice(int n, vector<vector<int>>& flights, int src, int dst, int k) {
        vector <int> G[n]; // 构建邻接矩阵
        vector <vector<int>> price(n, vector<int>(n, INF));
        for(auto flight : flights) {
            G[flight[0]].push_back(flight[1]); 
            price[flight[0]][flight[1]] = flight[2];
        }

        vector <vector<int>> dp(n, vector<int>(k + 2, 0));

        function<int(int, int)> dfs = [&](int i, int j) {
            if(dp[i][j] > 0) return dp[i][j];
            if(i == dst) {
                if(j <= k + 1) return dp[i][j];
                return INF;
            }
            int ans = INF;
            for(auto v : G[i]) {
                if(j < k + 1)
                    ans = min(ans, dfs(v, j + 1) + price[i][v]);
            }
            return dp[i][j] = ans;
        };

        int ans = dfs(src, 0);
        return ans == INF ? -1 : ans;
    }
};

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2131118.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智汇云舟斩获创客北京2024鲲鹏应用创新大赛北京区总决赛一等奖

近日&#xff0c;创客北京2024鲲鹏应用创新大赛华鲲振宇北京赛区总决赛在北京鲲鹏联合创新中心圆满举办。智汇云舟团队的参赛作品“视频孪生&#xff0c;把数字孪生升级为虚实共生”斩获鲲鹏原生开发赛道&#xff08;泛政府&#xff09;一等奖。 面向全球开发者的顶级赛事&…

python去除非页眉页脚,非背景非正式的图片、文字水印代码

import fitz import os import shutildef remove_watermarks_by_sizes(pdf_path, output_path, watermark_sizes, watermark_rects, watermark_texts):"""从PDF中删除特定大小的图片&#xff08;水印&#xff09;和特定的文字。参数:pdf_path (str): 输入PDF文件…

现金检测系统源码分享

现金检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision …

草莓大模型(o1 )同步——实战2024国赛数学建模C题

模型介绍 这是一系列全新AI模型&#xff0c;能推理复杂的任务&#xff0c;解决比以前科学、编程、数学模型更难的问题。o1 模型(草莓&#xff09;与 GPT-4o 的主要区别在于:它能够比前代更好地处理复杂的编程和数学问题&#xff0c;并能解释其推理过程.以往模型不同的是&#…

引用和指针的区别(面试概念性题型)

个人主页&#xff1a;Jason_from_China-CSDN博客 所属栏目&#xff1a;C系统性学习_Jason_from_China的博客-CSDN博客 概念概述 内存占用&#xff1a; 引用&#xff1a;引用一个变量时&#xff0c;实际上并不占用额外的内存空间&#xff0c;它就是原始变量的别名。指针&#xf…

裸金属 Ironic T和2024.1版本 功能比较

一、Train版 裸金属配置向导 1、系统环境 ansible 2.7.18 kolla-ansible 7.2.2.dev9[rootkolla-ansible-master ~]# python --version Python 2.7.5 [rootkolla-ansible-master ~]# cat /etc/centos-release CentOS Linux relea…

SAP B1 单据页面自定义 - 用户界面编辑字段

背景 接《SAP B1 基础实操 - 用户定义字段 (UDF)》&#xff0c;在设置完自定义字段后&#xff0c;如下图&#xff0c;通过打开【用户定义字段】可打开表单右侧的自定义字段页。然而再开打一页附加页面操作繁复&#xff0c;若是客户常用的定义字段&#xff0c;也可以把这些用户…

快充协议方案,Type-C接口受电端Sink取电快充协议芯片

快充协议芯片是确保充电器与设备之间兼容性的关键&#xff0c;它根据设备的需求提供合适的电压与电流&#xff0c;从 而实现更快速的充电体验。 快充协议芯片不仅仅是提升充电速度&#xff0c;更重要的是确保充电器与设备之间的兼容性&#xff0c;避免因协议不匹配导致的充电效…

从零开始打造一台简易计算机

从零开始打造一台可运行的简易计算机专题系列结合一个免费开源的 线上数字电路模拟器(仿真器), 从最基本的继电器(晶体管)功能讲起, 到最终完成一个可以批量执行指令的简易计算机. 跟随文中的步骤, 即可亲手在线上打造一台可运行的简易的计算机, 在此过程中, 将获得对计算机底…

2024lims实验室管理系统排名 6款LIMS软件厂商

随着实验室管理的不断升级&#xff0c;LIMS系统逐渐成为实验室不可或缺的一部分。这款实验室信息管理系统以其稳定性、多功能性和用户友好性在竞争激烈的市场中脱颖而出。 随着实验室管理的不断升级&#xff0c;LIMS系统逐渐成为实验室不可或缺的一部分。这款实验室信息管理系…

如何使用Python创建目录或文件路径列表

在 Python 中&#xff0c;创建目录或生成文件路径列表通常涉及使用 os、os.path 或 pathlib 模块。下面是一些常见的任务和方法&#xff0c;用于在 Python 中创建目录或获取文件路径列表。 问题背景 在初始阶段的 Python 学习过程中&#xff0c;可能遇到这样的问题&#xff1a…

NVG040W语音芯片:为制氧机带来个性化语音提示和报警功能

在当今社会&#xff0c;家庭医疗设备和健康保健产品越来越受到人们的关注。制氧机作为其中的一种&#xff0c;为许多需要氧气治疗的人们提供了重要的帮助。然而&#xff0c;对于许多用户来说&#xff0c;如何正确操作和维护这些设备仍然是一个挑战。为此&#xff0c;NVG040W语音…

点成分享 | 微生物浊度测量技术:比浊仪校准的最佳实践与策略

比浊仪通过检测悬浮液中微生物对光的散射程度来反映微生物含量。微生物浓度越高&#xff0c;透过的光越少&#xff0c;散射的光越多。因此&#xff0c;微生物浓度与透光度成反比&#xff0c;与吸光度成正比。该技术广泛应用于细菌浊度测定、抗生素药敏实验等微生物检测领域。 …

ElementPlus表单验证报错 formEl.validate is not a function

出现问题的代码 <!-- 密码重置弹框 --><el-dialog v-model"innerVisible" width"500" title"密码重置" append-to-body><el-form ref"ruleFormRef" style"max-width: 600px" :model"passForm" sta…

“鸿儒”——AIGC团队知识管理工作台

项目介绍 “鸿儒”——AIGC团队知识管理工作台是一项创新性的信息管理和协作平台&#xff0c;“鸿儒”立足于AIGC&#xff08;Artificial Intelligence Generated Content&#xff09;技术的前沿。该平台以机器学习和自然语言处理技术为核心&#xff0c;致力于协助团队更加高效…

Java实现邮箱发送功能详细步骤及注意事项?

Java实现邮箱发送怎么设置&#xff1f;JavaMail发送邮件的流程&#xff1f; 无论是用于用户注册验证、密码重置&#xff0c;还是系统通知&#xff0c;邮箱发送功能都能提供可靠的通信手段。AokSend将详细介绍Java实现邮箱发送功能的步骤&#xff0c;并探讨其中的注意事项。 J…

哪种掏耳朵方式好?高性价比的可视挖耳勺推荐!

耳朵健康作为人们个人健康的一种方式&#xff0c;它的重要性不可忽视。市面上的掏耳勺有多种&#xff0c;铁质掏耳勺、棉签、可视挖耳勺等&#xff0c;那么哪种掏耳勺最好用呢&#xff1f; 答案显而易见是可视挖耳勺&#xff0c;因为它摒弃了传统掏耳勺的耳勺头硬邦邦的问题&am…

jupyter notebook添加环境/添加内核

参考&#xff1a; jupyter notebook添加环境/添加内核&#xff08;超详细&#xff09;_python_leoound-GitCode 开源社区 Jupyter Notebook 切换虚拟环境_jupyter 选择环境-CSDN博客 1.激活想添加的环境 conda activate pytorch39 2.下载核 conda install ipykernel 3.按照…

MINICPM-V2_6之图像embedding的resampler-代码解读

目的 基于上一篇MINICPM-V2_6图像得到embedding-代码解读将图片patch找到对应的embedding&#xff08;包括位置embedding和像素embedding&#xff09;&#xff0c;embedding经过多层attention后会得到vision_embedding&#xff0c;vision_embedding的长度对应的是patch的个数&…

超链接/列表/多媒体/表格标记

1.超链接标记&#xff0c; 要将两个前端网页连接起来用什么标记呢&#xff1f; 答案是a标记&#xff0c;也就是超链接 下图就是两个html建立了超链接 效果是点击我是1号会跳转到我是2号那里 2.列表标记分为有序列表ol和无序列表ul, 每一列用li标签 <hr color"yell…