zl程序教程

您现在的位置是:首页 >  其他

当前栏目

华为的笔试这么简单,不考虑拿个offer吗?

华为 简单 这么 Offer 考虑 笔试
2023-06-13 09:13:01 时间

作者 | 梁唐

出品 | 公众号:Coder梁(ID:Coder_LT)

大家好,我是梁唐。

今天我们来看一套华为的校招笔试题,题目来源于牛客网,感兴趣想要亲自动手尝试的同学可以点击【阅读原文】跳转。

这套题的难度并不高,甚至可以说是很低,只要上学的时候认真学习,编码能力扎实,即使没刷过LeetCode没特地学过算法也一样能做出来。我曾经听华为的一个大佬分享过华为的招聘思路,华为相比于BAT这类互联网巨头对于应届生的能力要求并没有那么大。华为认为学校背景不错的同学大部分都有很强的学习能力,华为有能力将他们培养成才,所以对于学生在学校里所学到的能力要求相对就低了一些。而且华为的招聘缺口很大,如果要求卡得过严,肯定也就没办法保证数量了。

当年老梁毕业的时候,就频繁地收到华为的面试邀请短信,甚至我没去参加一面,居然还依然给我发信息让我直接去二面。虽然看起来有些跌价,但我也真的感受到了华为求贤若渴的诚意。

好了,废话不多说了,我们来看题目吧。

汽水瓶

有这样一道智力题:“某商店规定:三个空汽水瓶可以换一瓶汽水。小张手上有十个空汽水瓶,她最多可以换多少瓶汽水喝?”答案是 5 瓶,方法如下:先用 9 个空瓶子换3瓶汽水,喝掉 3 瓶满的,喝完以后 4 个空瓶子,用 3 个再换一瓶,喝掉这瓶满的,这时候剩 2 个空瓶子。然后你让老板先借给你一瓶汽水,喝掉这瓶满的,喝完以后用 3 个空瓶子换一瓶满的还给老板。如果小张手上有 n 个空汽水瓶,最多可以换多少瓶汽水喝?

数据范围:输入的正整数满足

1 \le n \le 100

注意:本题存在多组输入。

允许如题面所述向老板借汽水。

输入的 0 仅表示输入结束,并不用输出结果

输入描述:
输入文件最多包含 10 组测试数据,每个数据占一行,仅包含一个正整数 n( 1<=n<=100 ),表示小张手上的空汽水瓶数。n=0 表示输入结束,你的程序不应当处理这一行。
输出描述:
对于每组测试数据,输出一行,表示最多可以喝的汽水瓶数。如果一瓶也喝不到,输出0。
输入例子1:
3
10
81
0
输出例子1:
1
5
40
例子说明1:
样例 1 解释:用三个空瓶换一瓶汽水,剩一个空瓶无法继续交换
样例 2 解释:用九个空瓶换三瓶汽水,剩四个空瓶再用三个空瓶换一瓶汽水,剩两个空瓶,向老板借一瓶汽水喝完得三个空瓶换一瓶汽水还给老板 

解法

这题就是小学时候做过的智力题,trick的地方在于当我们有两个空瓶的时候,可以和老板借一个空瓶凑成3个,兑换之后再还给老板。

关于这个trick已经明确地写在题目说明里了,那么后面的就没有难度了,我们只需要模拟不停地兑换的这个过程。统计一下中途兑换成功的汽水数量即可。

#include <iostream>
#include <cstdio>
using namespace std;

int main() {
    int x; 
    
    while (~scanf("%d", &x) && x) {
        int ret = 0;
        while (x) {
            // 只剩一个空瓶时无法兑换
            if (x == 1) break;
            // 剩两个空瓶可以借一个空瓶兑换
            if (x == 2) {
                ret++;
                break;
            }
            ret += x / 3;
            x = (x % 3) + (x / 3);
        }
        printf("%d\n", ret);
    }
    
    return 0;
}

明明的随机数

明明想在学校中请一些同学一起做一项问卷调查,为了实验的客观性,他先用计算机生成了 N 个 1 到 1000 之间的随机整数( N≤1000 ),对于其中重复的数字,只保留一个,把其余相同的数去掉,不同的数对应着不同的学生的学号。然后再把这些数从小到大排序,按照排好的顺序去找同学做调查。现在明明把他已经用计算机生成好的 N 个随机数按照下面的输入描述的格式交给你,请你协助明明完成“去重”与“排序”的工作。

注:测试用例保证输入参数的正确性,答题者无需验证。

数据范围:

1 \le n \le 1000

,输入的数字大小满足

1 \le val \le 500
输入描述:
第一行先输入随机整数的个数 N ,接下来的 N 行再输入相应个数的整数。具体格式请看下面的"示例"。
输出描述:
返回多行,处理后的结果
输入例子1:
3
2
2
1
输出例子1:
1
2
例子说明1:
输入解释:
第一个数字是3,也即这个小样例的N=3,说明用计算机生成了3个1到1000之间的随机整数,接下来每行一个随机数字,共3行,也即这3个随机数字为:
2
2
1
所以样例的输出为:
1
2  

解法

题意非常明确,让我们完成了排序与去重。我们按照题意实现逻辑即可,排序可以使用algorithm库自带的sort函数。排序之后,我们去重只需要判断一下和之前一位的元素是否相同即可。

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    int n;
    scanf("%d", &n);
    vector<int> vt;
    for (int i = 0; i < n; i++) {
        int x;
        scanf("%d", &x);
        vt.push_back(x);
    }
    sort(vt.begin(), vt.end());
    printf("%d\n", vt[0]);
    for (int i = 1; i < n; i++) {
        if (vt[i] != vt[i-1]) printf("%d\n", vt[i]);
    }
    return 0;
}

进制转换

写出一个程序,接受一个十六进制的数,输出该数值的十进制表示。

数据范围:保证结果在

1 \le n \le 2^{31}-1
输入描述:
输入一个十六进制的数值字符串。
输出描述:
输出该数值的十进制字符串。不同组的测试用例用\n隔开。
输入例子1:
0xAA
输出例子1:
170

解法

进制转换也一样是基本功问题,首先要了解十六进制的表示方法。十六进制当中使用A-F表示10至15,并且在开始之前加上0x表示这是十六进制。

所以0xAA转换成十进制就是10 * 16 + 10 = 170。我们在转换进制的时候,可以忽略前两位,其次我们需要从末尾开始。因为末尾是最低位,每向左移动一位,它的基数乘以16。

我们只需要维护一下每一位对应的基数,再将每一位转换成十进制,和基数相乘最后累加即可。

#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
using namespace std;

int main() {
    string s;
    cin >> s;
    int ret = 0;
    int n = s.length();
    // 基数,每升高一位基数乘以16
    int base = 1;
    for (int i = n-1; i > 1; i--) {
        int cur;
        // 判断字母还是数字
        if (s[i] >= 'A' && s[i] <= 'Z') cur = 10 + s[i] - 'A';
        else cur = s[i] - '0';
        ret += cur * base;
        base *= 16;
    }
    printf("%d\n", ret);
    return 0;
}

到这里,华为的这套编程题就算是做完了。

相信大家也看得出来,题目非常基础,基本上都是常见的知识点,考察的都是基本功。据我所知华为的校招也是这个风格,并没有很多难题怪题,相对更质朴一些。

最后,再次感谢大家的阅读。

喜欢本文的话不要忘记三连~