星星博客 »  > 

说说华为机试注意点以及三道题的解题思路

最近有机会尝试做了一下华为机试题,感觉整个过程还是挺有意思的,分享一下经历。

前面说一下体验和注意点,后面附上题目和解题思路,本文使用python解题

一、体验和一些注意点

1、总体的感觉:

难度比预想的小挺多,练习题有些很难的,涉及算法啥的,实际没有考到。做是能做出来的,最后一道题测试用例有些没通过,应该是场景考虑不够全面。

2、题型:

考试时长180分钟。三道应用编程题,生活中的问题,用程序解决。前两道各100分,第三道200分。前两道相对简单点,第三道可能会涉及到比较难的算法。可以自由选择编程语言,例如C,C++,Java,Python等,没有sql。

3、计分逻辑(个人猜测):

考完后思考了一下,分数的计算逻辑应该是按照测试用例的通过比例来算的,例如:最后一道题总分200分,测试用例通过率50%, 那么你的得分就是100分。

4、规则:

邮件发送考试链接和规则,附有练习地址,7天内考完即可,错过了半年内无法再考,作弊则以后没机会参与华为项目。
可以在浏览器上编辑调试测试代码,也可以在本地IDE写好粘贴上去,但不允许使用现有代码。
需要自己处理输入输出,可能会涉及多行输入输出问题,还可能给你个数组格式的字符串,需要自己处理成真正的数组,比较麻烦的可能是多行输入的同时还有矩阵,不过考试时有提供处理的案例,不用担心。

5、监控规则:

考试前打开摄像头,开启浏览器录屏监控,扫码打开小程序监控手机,手机屏幕必须全程亮着,停留在小程序界面,息屏或者跳出小程序三次则结束考试。允许使用纸笔,允许中途离开摄像头,最好2分钟内回来。

6、考前练习:

牛客网有华为机试练习,至少有两百道题左右,有简单的也有难的,难的一般是算法题,会限制时间复杂度和空间复杂度,有可能因为占用内存过多或者运行时间超长而无法通过

7、考试时感觉比较坑的地方:

7.1、测试详情看不到:

考前的练习有提供测试用例的预期结果和实际结果对比,不通过的话对比结果也比较容易找到问题在哪。实际考试虽然也有提供测试用例,但你无法知道测试用例是怎样的,也不知道哪些没通过,要是遇到判断场景比较多的,考虑少了就只能自己摸瞎找问题了,最好练一下如何批量生成测试用例。

7.2、测试提供的场景太简单

考试时是有提供一两个测试例子用来示范输入和输出结果的,但是很普通,你需要自己去考虑特殊的场景。就好比如让你计算考勤情况判断该员工能不能拿全勤奖,有多个要求,其中一个要求是不能出来连续的迟到/早退,结果我脑补的场景是今天迟到并且明天早退,或者今天早退并且明天迟到则无法拿全勤奖,然后部分测试用例没通过。由于看不到测试详情,就只能摸瞎一个个条件重新考虑,最终发现是这个要求下面有两个场景没考虑到: 连续两天都迟到或者连续两天早退也是不能拿全勤奖的。

二、接下来说一下遇到的题目

1、第一道题比较简单:字符串的去重和排序

题目:两次输入,各输入一行小写字母构成的字符串,要求从第一次输入的字符串中找出第二行字符串中有的,按照ascii编码排序, 最终输出没有重复字母的字符串。

示例:
输入:
bacha
bbaaccedfg

输出:
abc

解题思路:
几乎就是字符串的基本操作,没啥好说的

s = input()
s2 = input()
s1 = ''

for i in s:
    if s2.count(i) > 0:
        if i in s1:
            pass
        else:
            s1 += i

s1 = ''.join(sorted(s1))
print(s1)

2、第二题稍微增加了难度:考勤问题,考的主要是字符串的操作和逻辑判断

一公司使用字符串来记录考勤,首行输入的数字代表接下来需要判断的员工数,后面每一行代表一个员工的出勤记录,每行不超过10000个字符,每个单词代表每天的出勤情况,
present代表正常出勤,absent代表缺席,late代表迟到,leaveearly代表早退,单词之间用空格隔开。
如下所示:
present
present present

现需要判断每个员工是否能获得全勤奖, 获得全勤奖的规则是:缺勤不超过1次,没有连续的迟到/早退,
任意连续7天内出现缺勤/迟到/早退的次数不超过3次。

输出要求:结果输出为一行,以空格隔开

示例1:
输入:
2
present
present present

输出:
true true

示例2:
输入:
2
present
absent present late present present present present leaveearly late present present

输出:
true false

其实就是一个逻辑判断,看你考虑的场景够不够全面

# 自己编的测试用例三,相比官方给的2个简单测试用例,覆盖场景较多
s1 = 'present'
s2 = 'absent present late present present present present leaveearly late present present'
s3 = 'absent present late present present present present leaveearly present present'
s4 = 'absent present late present present present present late leaveearly present present'
s5 = 'absent present present present late present present leaveearly present present present late present present'
s6 = 'absent present present present present present present present present late late'
# s = ''
def can_award(s1):
    l = s1.split(' ')
    if s1.count('absent') > 1:
        # 缺勤大于1
        return 'false'
    if s1.count('late leaveearly') > 0 or s1.count('leaveearly late') >0 \
            or s1.count('late late') >0 or s1.count('leaveearly leaveearly')> 0:
        # 有连续的迟到/早退
        return 'false'
    for i in range(len(l)):
        # 当查到有缺勤或者迟到或者早退时,获取往后的6个记录,检查是否有迟到早退
        this = l[i]
        if this == 'absent' or this == 'late' or this == 'leaveearly':
            c = 0
            l1 = l[i+1: i+7]
            print(l1)
            c += l1.count('absent')
            c += l1.count('late')
            c += l1.count('leaveearly')
            print(c)
            if c > 2:
                return 'false'
    return 'true'

import sys

# 读取第一行的n
n = int(sys.stdin.readline().strip())
l = []
for i in range(n):
    # 读取每一行
    line = sys.stdin.readline().strip()
    print(line)
    l.append(can_award(line))
print(' '.join(l))

3、第三题:书本叠放问题

题目:假设书本的叠放有这样的规则,当A书的宽度和高度都大于B书时,可以将其B书置于A的上方,堆叠摆放,请设计一个程序,根据输入的书本长宽,计算最多可以堆叠摆放多少本书?

示例:
输入:
[[16,15], [13, 12], [15, 14]]

输出:
3

解题思路:
1、先处理好输入的字符串,转成python的列表
2、列表内嵌列表,可以考虑转成字典并按键排好序,方便快速比较

# 官方给的测试用例
# s = '[[16,15], [13, 12], [15, 14]]'
# 自己写的测试用例
s = '[[16,15], [16, 14], [13, 12], [15, 14]]'
# s = input()
s = s.replace(' ', '')
s = s.replace('],[', '];[')
l = s[1:-1].split(';')
# print(l)
d = {}
for i in l:
    # 如果该键已存在d中,需要比对值的大小,取大的
    if i[1:-1].split(',')[0] in d.keys():
        d[i[1:-1].split(',')[0]] = int(i[1:-1].split(',')[1]) if int(i[1:-1].split(',')[1]) >= d[i[1:-1].split(',')[0]] \
            else d[i[1:-1].split(',')[0]]
    else:
        d[i[1:-1].split(',')[0]] = int(i[1:-1].split(',')[1])

# print(d)
d2 = {}
for j in sorted(d, reverse=True):  # 按键从大到小排序
    d2[j] = d[j]

keys = list(d2.keys())   # 排完续后的键值对
# print(keys)
c = 0
for k,v in d2.items():
    k_index = keys.index(k)
    for i in keys[k_index+1::]:
        if v > d2[i]:
            c += 1
print(c)

第三题考的时候没有完全通过所有测试用例,考完改进了一下,这里上的是改后的代码,目前没测出什么问题,有兴趣的朋友可以多写几个测试用例测一下,有发现不对的结果可以私信我说一下。

一开始以为会有些很难的算法,所以这几天一直在看算法,做的时候发现还好没遇到,考得过可能跟运气也有关。

另外,好的测试很重要,如果测试用例覆盖场景足够多,可以更快地找出程序的问题在哪。

相关文章