又是一年春招时,有幸收到华为自动驾驶算法岗,之前刷题不多,在此汇总下牛客网的真题,主要采用Python编写,个人觉得语言只是实现工具而已,并不是很关键,Python简洁易懂,更加适合算法工程师快速验证idear,避免重复造轮子的繁琐,希望对看合集的你有些许帮助!
- 「解析」牛客网-华为机考企业真题 1-20
- 「解析」牛客网-华为机考企业真题 21-40
- 「解析」牛客网-华为机考企业真题 41-60
- 「解析」牛客网-华为机考企业真题 61-80
- 「解析」牛客网-华为机考企业真题 81-108
文章目录
- HJ41 称砝码
- ★★★ HJ42 学英语
- HJ43 迷宫问题
- ★★★ HJ44 Sudoku
- HJ45 名字的漂亮度
- HJ46 截取字符串
- HJ48 从单向链表中删除指定值的节点
- HJ50 四则运算
- HJ51 输出单向链表中倒数第k个结点
- HJ52 计算字符串的编辑距离
- HJ53 杨辉三角的变形
- HJ54 表达式求值
- HJ55 挑7
- HJ56 完全数计算
- HJ57 高精度整数加法
- HJ58 输入n个整数,输出其中最小的k个
- HJ59 找出字符串中第一个只出现一次的字符
- HJ60 查找组成一个偶数最接近的两个素数
HJ41 称砝码
每次加一块砝码,得到所有组合,使用set去重。这是一种思路,我看很大一部分同学都是使用n种不同砝码进行组合,那样的话时间复杂度稍微低一点,实际看个人觉得哪种方式更好理解。
while True:
try:
n = int(input())
m = input().split(" ")
x = input().split(" ")
# mx为所有砝码,比如示例mx为[1, 1, 2]
mx, l = [], {0}
for i in range(n):
mx.extend([int(m[i])] * int(x[i]))
for i in mx:
# 每次加一块砝码,使用union(并集)得到新去重的组合,如果不使用union则稍微麻烦一点,需要考虑循环中改变set
l = l.union({i+j for j in l})
print(len(l))
except:
break
★★★ HJ42 学英语
num1 = ['zero','one','two','three','four','five','six',
'seven','eight','nine','ten','eleven','twelve',
'thirteen','fourteen','fifteen','sixteen',
'seventeen','eighteen','nineteen']
num2 = [0,0,'twenty','thirty','forty','fifty','sixty',
'seventy','eighty','ninety']
# 100以内转英文
def n2w(n):
if n > 0:
if n < 20:
word.append(num1[n])
else:
word.append(num2[n//10])
if n%10 != 0:
word.append(num1[n%10])
# 1000以内转英文
def hun(n):
if n >= 100:
word.append(num1[n//100])
word.append('hundred')
if n % 100 != 0:
word.append('and')
n2w(n%100)
while True:
try:
n = int(input())
except:
break
else:
word = []
a = n % 1000 # 个十百位
b = (n//1000) % 1000 # 个十百千
c = (n//1000000) % 1000 #个十百m
d = n // 1000000000 # 个十百b
if d > 0:
hun(d)
word.append('billion')
if c > 0 :
hun(c)
word.append('million')
if b > 0:
hun(b)
word.append('thousand')
if a > 0 :
hun(a)
print(' '.join(word))
HJ43 迷宫问题
while True:
try:
m, n = list(map(int, input().split()))
maze = []
for _ in range(m):
maze.append(list(map(int, input().split())))
def walk(i, j, pos=[(0, 0)]):
if j+1 < n and maze[i][j+1] == 0: # 向右
if (i, j+1) not in pos:
walk(i, j+1, pos + [(i, j+1)])
if j-1 >= 0 and maze[i][j-1] == 0: # 向左
if (i, j-1) not in pos:
walk(i, j-1, pos + [(i, j-1)])
if i+1 < m and maze[i+1][j] == 0: # 向下
if (i+1, j) not in pos:
walk(i+1, j, pos + [(i+1, j)])
if i-1 >= 0 and maze[i-1][j] == 0: # 向上
if (i-1, j) not in pos:
walk(i-1, j, pos + [(i-1, j)])
if (i, j) == (m-1, n-1): # 到达出口
for p in pos:
print('(' + str(p[0]) + ',' + str(p[1]) + ')')
walk(0, 0)
except:
break
★★★ HJ44 Sudoku
def check(sudoku,i,j): #判断这个数填入数独的i,j位置是否合理
for k in range(9):
if(sudoku[i][k] == sudoku[i][j]) and (k != j): #若是这一列有重复的数据,认为这个数非法
return False
for k in range(9):
if(sudoku[k][j] == sudoku[i][j]) and (k != i): #若是这一行有重复的数据,认为这个数非法
return False
m = 3*(i // 3) #m,n分别是i,j位置所在的3*3格子的最左上角的位置
n = 3*(j // 3)
for k in range(3):
for z in range(3):
if(sudoku[m+k][n+z] == sudoku[i][j]) and ((m+k) != i) and ((n+z) != j): #判断所在3*3格子是否有重复的数据
return False
return True #若都没有,那么认为这个数在重复上面没有问题
def find_sudoku(sudoku):
for i in range(9):
for j in range(9):
if(sudoku[i][j] == 0): #若是找到为0的
for t in range(1,10): #在这个位置依次填入1-9尝试
sudoku[i][j] = t
if(check(sudoku,i,j)) and (find_sudoku(sudoku)): #若是满足数独要求,而且填完这个数之后的0也能被成功填写
return True #认为成功
sudoku[i][j] = 0 #如果1-9都不行认为是之前填的数不合适,恢复这次填的数
return False #返回之前一个false
return True 走到这一步认为所有的空都被填满,返回成功
while True:
try:
sudoku = []
sudoku_index = []
for i in range(9):
a = list(map(int,input().split()))
sudoku.append(a) #将数独输入
find_sudoku(sudoku)
for i in range(9):
print(*sudoku[i])
except:
break
HJ45 名字的漂亮度
while True:
try:
#获取输入的单词数量
N = int(input())
while N:
#获取输入的单词
data = input()
#去重存入字典
d = {}
for word in data:
if word not in d:
d[word] = 1
else:
d[word] = d[word] + 1
d1 = sorted(d.values() ,reverse=True)
ans = 0
m = 0
for word in d1:
ans = ans + (26-m)*word
m = m + 1
print(ans)
N = N - 1
except:
break
HJ46 截取字符串
while True:
try:
str_input = input()
k = int(input())
print(str_input[:k])
except:
break
HJ48 从单向链表中删除指定值的节点
while True:
try:
num = list(map(int,input().split()))
n = len(num)
new = []
for i in range(2,n-1,2):
if num[i+1] not in new: #没有就追加
new.append(num[i+1])
new.append(num[i])
else: #有就插队
ind = new.index(num[i+1])
new.insert(ind+1,num[i])
#循环删除节点
try:
while True:
new.remove(num[-1])
except:
pass
#输出
new = [str(x) for x in new]
print(' '.join(new))
except:
break
HJ50 四则运算
while True:
try:
s=input()
s=s.replace('{', '(')
s=s.replace("}",")")
s=s.replace("[","(")
s=s.replace("]",")")
print(int(eval(s)))
except:
break
HJ51 输出单向链表中倒数第k个结点
链表做法,直接逆向遍历
class Node(object):
def __init__(self, val=0):
self.val = val
self.next = None
while True:
try:
head = Node()
count, num_list, k = int(input()), list(map(int, input().split())), int(input())
while k:
head.next = Node(num_list.pop())
head = head.next
k -= 1
print(head.val)
except EOFError:
break
HJ52 计算字符串的编辑距离
#动态规划经典题目
#nowcoder不能导入numpy模块,只能手工创建二维数组
#重点注意二维数据的创建方法,重点注意其横竖坐标,注意注意
#dp = [[1 for i in range(n+1)] for j in range(m+1)],横坐标是 n, 竖坐标是m
while True:
try:
str1 = input()
str2 = input()
m = len(str1)
n = len(str2)
dp = [[1 for i in range(n+1)] for j in range(m+1)]#重点注意二维数据的创建方法,重点注意其横竖坐标,注意注意
for i in range(n+1):
dp[0][i] = i
for j in range(m+1):
dp[j][0] = j
for i in range(1,m+1):
for j in range(1,n+1):
if str1[i-1] == str2[j-1]:#如果当前两个字母相同,则跳过,步数不增加
dp[i][j]=dp[i-1][j-1]
else: #如果两个字母不同,则有三种方式可以达成,删除、插入、替换,选择最小的前状态,步数加1
dp[i][j] = min(dp[i-1][j-1],dp[i][j-1],dp[i-1][j])+1
print(dp[m][n])
except:
break
HJ53 杨辉三角的变形
import sys
alt=[2,3,2,4] #发现规律,从第三行开始2324循环
for line in sys.stdin:
n=int(line.strip())
if n<3:
print(-1)
if n>=3:
print(alt[(n-3)%4]) #所以对4求余,映射到上面alt列表中
HJ54 表达式求值
while True:
try:
print(int(eval(input())))
except:
break
HJ55 挑7
while True:
try:
n = int(input())
c = 0
for i in range(1,n+1):
if i % 7 == 0:
c += 1
elif str(i).count('7') > 0 :
c += 1
print(c)
except:
break
HJ56 完全数计算
while True:
try:
n=int(input())
L=[]
for i in range(1,n):
p=0
for y in range(1,i):
if i%y==0:
p=p+y
if i==p:
L.append(p)
print(len(L))
except:
break
HJ57 高精度整数加法
python语言支持大整数,不受位数限制
因此转成整型之后直接相加即可
while True:
try:
n1 = int(input())
n2 = int(input())
print(n1+n2) # 直接输出整型数字相加之和的结果
except:
break
HJ58 输入n个整数,输出其中最小的k个
step1:首先输入n,k这两个参数(因为input()后是字符串类型,所以需要将n,k转换为int类型,这时我们需要使用list(map())函数);
step2:其次,输入一个整数数组num(原理同上,也需要转换为int型,同样需要list(map())函数;)
step3:使用sorted()函数,对num整数数组进行排序;
step4:使用for循环,遍历“排序后的、且使用切片切割好的”整数数组num;
step5:逐个打印,并使用空格分开
n,k = list(map(int,input().split()))
num = list(map(int,input().split()))
num = sorted(num)
for i in num[:k]:
print(i,end=' ')
HJ59 找出字符串中第一个只出现一次的字符
while True:
try:
s = input()
for i in s:
if s.count(i) == 1:
print(i)
break
else:
print('-1')
except:
break
HJ60 查找组成一个偶数最接近的两个素数
从输入的偶数的一半开始找,到2,找出其中所有素数,再判断另外一个数是不是素数
while True:
try:
n = int(input())
prime = []
for i in range(int(n/2), 1,-1):
for x in range(2,i):
if i%x == 0 or (n-i)%x == 0:
break
else:
prime.append(i)
print(prime[0])
print(n-prime[0])
except:
break