又是一年春招时,有幸收到华为自动驾驶算法岗,之前刷题不多,在此汇总下牛客网的真题,主要采用Python编写,个人觉得语言只是实现工具而已,并不是很关键,Python简洁易懂,更加适合算法工程师快速验证idear,避免重复造轮子的繁琐,希望对看合集的你有些许帮助!
- 「解析」牛客网-华为机考企业真题 1-20
- 「解析」牛客网-华为机考企业真题 21-40
- 「解析」牛客网-华为机考企业真题 41-60
- 「解析」牛客网-华为机考企业真题 61-80
- 「解析」牛客网-华为机考企业真题 81-108
文章目录
HJ21 简单密码
""" 懒人做法 """
while True:
try:
A="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
B="22233344455566677778889999bcdefghijklmnopqrstuvwxyza0123456789"
list1=[]
list2=[]
for i in A:
list1.append(i)
for i in B:
list2.append(i)
C=[]
a=input()
for i in a:
if i in list1:
C.append(list2[list1.index(i)])
else:
C.append(i)
print(''.join(C))
except:
break
方法二
while True:
try:
s = input()
res = []
for i in s:
if i.isdigit():
res.append(i)
elif i.isupper() and i != 'Z':
res.append(chr(ord(i.lower()) + 1)) # 大小写切换
elif i == 'Z':
res.append('a')
else:
if i in 'abc': # if ord('a') <= ord(oder[i]) <= ord('c'):
res.append('2')
elif i in 'def':
res.append('3')
elif i in 'ghi':
res.append('4')
elif i in 'jkl':
res.append('5')
elif i in 'mno':
res.append('6')
elif i in 'pqrs':
res.append('7')
elif i in 'tuv':
res.append('8')
else:
res.append('9')
print(''.join(res))
except:
break
HJ22 汽水瓶
有点离谱的思路,恰好是2个瓶子最终能换一瓶,所以直接整除2即可,但标准解决方案应该是使用递归的思路
import sys
data = sys.stdin
for x in data:
x = int(x.strip())
if x != 0:
print(int(x // 2))
递归思路
import sys
def f(n):
if n == 0: return 0
if n == 1: return 0
if n >=2: return f(n-2) + 1
if __name__ == '__main__':
data = sys.stdin
for x in data:
x = int(x.strip())
if x != 0:
print(f(x))
HJ23 删除字符串中出现次数最少的字符
s = input()
dic = {}
for i in s:
if i in dic:
dic[i] += 1
else:
dic[i] = 1
MIN = min(dic.values())
for i in s:
if dic[i] == MIN:
s = s.replace(i,'')
print(s)
★★ HJ24 合唱队
# 动态规划
def lengthOfLIS(lst):
dp = []
for i in range(len(lst)):
dp.append(1)
for j in range(i):
if lst[i] > lst[j]:
dp[i] = max(dp[i], dp[j] + 1)
return dp # 每人左边可以站的人数
while True:
try:
n, heights = int(input()), list(map(int, input().split()))
# dp1:每人左边可以站的人数,dp2:每人右边可以站的人数
dp1, dp2 = lengthOfLIS(heights), lengthOfLIS(heights[::-1])[::-1]
res = []
for i in range(len(dp1)):
res.append(dp1[i] + dp2[i] - 1)
print(n-max(res))
except:
break
★★★ HJ25 数据分类处理
while True:
try:
s1 = input().split()[1:]
s2 = list(set(map(int, input().split()[1:])))
s2.sort()
rst = []
for num in s2:
tmp = []
for i, sub in enumerate(s1):
if str(num) in sub:
tmp.extend([str(i), str(sub)])
if tmp:
rst.extend([str(num), str(len(tmp)//2)] + tmp)
print(str(len(rst)) + " " + " ".join(rst))
except:
break
HJ26 字符串排序
sorted(iterable,str.upper)就可以实现1)字符由A到Z的排序2)能够实现同字母(A与a算同字母),由输入先后书序排列。
str.isalpha实现的是如果字符串至少有一个字符并且所有字符都是字母则返回 True,否则返回 False。
try:
s =input()
a = ''
for i in s:
if i.isalpha():
a += i
b = sorted(a, key=str.upper)
index = 0
d = ''
for i in range(len(s)):
if s[i].isalpha():
d += b[index]
index += 1
else:
d += s[i]
print(d)
except:
break
HJ27 查找兄弟单词
while True:
try:
data1 = input().split() # 读取输入数据,并且转换为列表
n1 = data1[0] # 获取单词的个数
n2 = data1[-1] # 按字典排序的第几个兄弟词
data2 = data1[1:-2] # 获取输入的n个单词
data3 = data1[-2] # 获取兄弟词
n3 = 0 # 用于存储兄弟词的数量
data4 = [] # 用于存储兄弟词
for word in data2:
if word == data3:
continue
elif sorted(word) == sorted(data3):
n3 = n3 + 1
data4.append(word)
print(n3)
data5 = sorted(data4) # 将兄弟词按照字典排序
print(data5[int(n2)-1])
except:
break
★★★★★ HJ28 素数伴侣
如果是素数,一定是奇数和偶数结合(奇数)才有可能是素数,所以将需要配对的数分为两组,一组是奇数,一组是偶数,通过匈牙利算法求得最大的配对数
此题为匈牙利算法解决二分图最大匹配问题。我们可以把数据分为偶数,奇数两部分,然后进行配对(因为素数为一奇一偶的和)。
import math
def isPrime(x):
if x<=3:
return x>1
for i in range(2, int(math.sqrt(x)+1)):
if x%i ==0:
return False
else:
return True
//该odd是否有匹配的even,返回boolean值
def match(odd):
// 对偶数进行遍历,看是否与该奇数配对
for i in range(n):
// 若两数和为素数且该偶数在这轮循环中没有被访问过
if isPrime(odd+ evens[i]) and vis[i]==0:
// 将该偶数标记为已访问
vis[i]=1
// p[i]=odd 为该偶数对应的odd储存值,如果该偶数没有奇数odd匹配,则为0,否则返回所匹配的odd
// 如果p[i]还未匹配或者 p[i]已经有其他匹配的odd2,且该match(odd2)还有其他可以匹配的偶数(True)
if p[i]==0 or match(p[i]):
// 取代原来的p[i]=odd2,变为 p[i]=odd
p[i]=odd
return True
return False
while True:
try:
n = int(input())
nums = list(map(int,input().split()))
odds = []
evens = []
for num in nums:
if num%2==0:
evens.append(num)
else:
odds.append(num)
m = len(odds)
n = len(evens)
s = 0
p=[0]*n
for num in odds:
//每一次循环的vis必须要清空
vis = [0]*n
if match(num):
s+=1
print(s)
except:
break
HJ29 字符串加解密
用b判断是加密还是解密, 直接用映射的方法输出
def check(a,b):
L1 = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
L2 = "BCDEFGHIJKLMNOPQRSTUVWXYZAbcdefghijklmnopqrstuvwxyza1234567890"
result = ""
if b == 1:
for i in a:
result += L2[L1.index(i)]
elif b == -1:
for i in a:
result += L1[L2.index(i)]
return result
while True:
try:
print(check(input(),1))
print(check(input(), -1))
except:
break
★★★ HJ30 字符串合并处理
while True:
try:
str = ''.join(input().split())
except:
break
else:
# 第二步奇偶排列
oushu = [str[x] for x in range(0,len(str),2)]
jishu = [str[x] for x in range(1,len(str),2)]
oushu.sort()
jishu.sort()
paixu = []
for i in range(len(str)):
n = int(i/2)
if i % 2 == 0:
paixu.append(oushu[n])
else:
paixu.append(jishu[n])
#第三步转换字符
for i in paixu:
try:
b=bin(int(i,16))[2:]
b = '0'*(4-len(b)) + b if len(b)<4 else b
b = b[::-1]
b = hex(int(b, 2))[2:].upper()
print(b,end='')
except:
print(i,end='')
print()
HJ31 单词倒排
a=input().strip()
for i in range(len(a)):
if not a[i].isalpha():
a=a.replace(a[i], ' ')
b=a.split(' ')
if ' ' in b:
b = b.pop(' ')
b.reverse()
print(' '.join(b))
HJ32 密码截取
str = input()
n = len(str)
list = []
for i in range(0,n-1):
for j in range(1,n):
if str[j] == str[i] and str[i+1:j] == str[j-1:i:-1]:
list.append(len(str[i:j+1]))
print(max(list))
HJ33 整数与IP地址间的转换
用到int和bin函数,在10进制和2进制之间反复转换
def transfer_ip2num(ip):
ip_list = ip.split('.')
bin_str = ''
for x in ip_list:
bin_str += bin(int(x))[2:].rjust(8,'0')
return int('0b'+ bin_str, 2)
def transfer_num2ip(num):
result = ''
bin_str = bin(int(num))[2:].rjust(32,'0')
for idx in range(4):
result = result + str(int('0b' + bin_str[idx*8:idx*8+8], 2)) + '.'
return result[:-1]
if __name__ == '__main__':
while True:
try:
print(transfer_ip2num(input()))
print(transfer_num2ip(input()))
except EOFError: break
HJ34 图片整理
while True:
try:
print(''.join(sorted(input())))
except EOFError: break
HJ35 蛇形矩阵
观察第一行的规律符合累加求和公式;(n+1)n/2
第二行的规律则是第一行的 ((n+1)n/2) - 1
第三行的规律则是第一行的 ((n+1)n/2) - 2
第四行的规律则是第一行的 ((n+1)n/2) - 3
当i = 1 时,j = 1,2,3,4 进入循环;
当i = 2 时,j = 2,3,4
当i = 3 时,j = 3,4
当i = 4 时,j = 4
n = int(input().strip())
for i in range(1,n+1) :
for j in range(i,n+1) :
# 输出的公式是转化后的,其实也可以写去括号前,
# int()的作用是将结果转化成整型,因为计算结果是有小数的,
# end = ' '作用是将内层循环的计算结果以空格隔开
print(int(((j+j**2)/2)-i+1),end = ' ')
print() # 一次循环结束后打印空,用作换行
HJ36 字符串加密
letterlst = []
for i in range(26):
letterlst.append(chr((ord("a")+i)))
while True:
try:
key = input().upper()
string = input()
alpha = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
encrypted_map = []
res = ''
for i in range(len(key)):
if key[i] not in encrypted_map:
encrypted_map.append(key[i])
for j in alpha:
if j not in encrypted_map:
encrypted_map.append(j)
for k in string:
if k.islower():
res += encrypted_map[alpha.index(k.upper())].lower()
else:
res += encrypted_map[alpha.index(k.upper())]
print(res)
except:
break
HJ37 统计每个月兔子的总数
这道题目不是很难,但是我们必须要深刻理解题目的含义。
根据题意,我们可以知道,兔子有三种状态:
(1)年龄为3个月及以上:可以生产,设为num。
(2)年龄为2个月:不可以生产,设为num2。
(3)年龄为1个月:不可生产,刚出生,设为num1。
我们可以先分析输入输出,可以得出,我们最开始获得的是一只一个月的兔子,并不是一只成年的兔子,因此在最初的两个月中,该兔子需要成长,不能生育,这是需要特别注意的,题目没有具体说清楚。
因此,我们可以假设num,num1,num2初始值为0,针对第n月的情况,我们可以使用for循环处理,在循环中,需要特别处理前两个月的情况,因为这两个月,没有成年的兔子可以生育,当到达第三个月以及以后时,我们可以按照正常的逻辑进行处理。
首先,我们先讨论特例的情况。当n=1时,此时三种兔子都是0,加入第一只小兔子,设num1=1;当n=2时,没有成年的兔子可以生产,此时有一只兔子的年龄增加一岁。
当n>=3时,此时,已有可以生产的成年兔子了,num2增加一月,此时成年兔子为num=num+num2,而num1中的兔子年龄增加一月,num2=num1。当月新出生的兔子num1=num。
最后输出三种兔子的总和就是最终的结果。
while True:
try:
n = int(input())
num = 0
num1 = 0
num2 = 0
for i in range(n):
num += num2
num2 = num1
if num==0 and num2 == 0:
num1 = 1
elif num==0 and num2 == 1:
num1 = 0
else:
num1 = num
print(num+num1+num2)
except:
break
斐波那契数列:1 1 2 3 5 8 13 21 34 f(n)=f(n-1)+f(n-2) n>2,n从0开始
1.递归法:
while True:
try:
month=int(input())
n=month-1
def func(n):
if n<2:#基线条件
return 1
else:#递归条件
return func(n-1)+func(n-2)
print(func(n))
except:
break
2.循环列表
import sys
for s in sys.stdin:#s=input()读入数据的1行
month=int(s)
L=[]
for i in range(month):
if i<2:#前两个月都为1
total=1
L.append(total)
else:
total=L[i-1]+L[i-2]#之后均为前两个数的和
L.append(total)
print(L[-1])#最后的列表L=[1, 1, 2, 3, 5, 8, 13, 21, 34]
HJ38 求小球落地5次后所经历的路程和第5次反弹的高度
while True:
try:
H = int(input())
S = 0 - H
for i in range(5):
S = S + H * 2
H = H/2
print(float(S))
print(float(H))
except:
break
★★ HJ39 判断两个IP是否属于同一子网
直接采用 & 进行 位运算
while True:
try:
x = input().split('.')
y = input().split('.')
z = input().split('.')
m, n = [], []
for i in range(len(x)):
x[i] = int(x[i])
y[i] = int(y[i])
z[i] = int(z[i])
if x[0]!= 255 or x[3]!=0 or max(x+y+z)>255 or min(x+y+z)<0:
print('1')
else:
for i in range(len(x)):
m.append(int(x[i]) & int(y[i]))
n.append(int(x[i]) & int(z[i]))
if m == n:
print('0')
else:
print('2')
except:
break
通过 bin转化为 2进制,然后替换掉 0b
while True:
try:
x=input().split(".")
y=input().split(".")
z=input().split(".")
m=[]
n=[]
for i in range (len(x)):
x[i]=int(x[i])
y[i] = int(y[i])
z[i] = int(z[i])
if x[0]!=255 or x[3]!=0 or max(x+y+z)>255 or min(x+y+z)<0:
print("1")
else:
for i in range (len(x)):
x[i]=bin(x[i]).replace("0b","")
y[i] = bin(y[i]).replace("0b","")
z[i] = bin(z[i]).replace("0b","")
m.append(int(x[i],2)&int(y[i],2))
#m[i]=m[i].replace("0b","")
n.append(int(x[i],2)&int(z[i],2))
#n[i] = n[i].replace("0b", "")
if m==n:
print("0")
else:
print("2")
except:
break
HJ40 统计字符
通过 re 正则化求解
import re
while True:
try:
s = input()
print(len(''.join(re.findall(r'[a-zA-Z]+', s))))
print(len(''.join(re.findall(r' ', s))))
print(len(''.join(re.findall(r'\d', s))))
print(len(''.join(re.findall(r'[^a-zA-Z0-9 ]+', s))))
except:
break
直接统计
while True:
try:
s=input()
l=[0,0,0]
for i in s:
l[0]+=int(i.isalpha())
l[1]+=int(i==' ')
l[2]+=int(i.isnumeric())
print(l[0])
print(l[1])
print(l[2])
print(len(s)-l[0]-l[1]-l[2])
except:
break