华为python语⾔通⽤编程规范-华为2019年3⽉27⽇实习⽣笔试
题及解答(Python。。。
3⽉27⽇做了华为笔试,3道题2⼩时。当时没有拍照,现在凭记忆将题⽬和代码叙述⼀遍,⽅便后⼈。前⾯将把三道题分别列⼀下,供后来者⾃⼰做。在后⾯说明⼀下⾃⼰的写法
第⼀题:题⽬说的⽐较复杂,读懂题意之后⼤致是,9个字符⼀组,每组的第⼀个字符是标志位,后⾯8个字符是地址。如果标志位是0,地址逆序,标志位是1地址不变。输⼊说明:⼀个字符串,有多组字符,中间没有空格。输出说明:输出最后的地址,每组地址⽤空格隔开,最后⼀个输出不需要空格。时间:C/C++1秒其他2秒
第⼆题:简⽽⾔之就是TSP问题。蜂巢在坐标(0,0)的位置,有五处花丛,蜜蜂从蜂巢出发,要把五处花丛的花蜜采完再回到蜂巢,最短距离是多少。输⼊说明:⼀⾏输⼊,10个数分别是五处花丛的坐标(x1,y1,x2,y2,x3,y3,x4,y4,x5,y5),⽤空格隔开。输出说明:输出最短距离,距离向下取整。时间:C/C++5秒其他10秒
第三题:切⽔果游戏。有⼀个40×50的⽅格,⾥⾯有n(1≤n≤36)个⽔果,每⼀⼑可以横切,竖切以及左斜切与右斜切四种⽅式。想要切完所有⽔果,最少需要多少⼑。输⼊说明:第⼀⾏是说过个数n,接下
来的n⾏是⽔果的横纵坐标。输出说明:输出最少需要的⼑数。(PS:原题有图,这⾥⽆图解释⼀下切割⽅式,横切就是所有x相同的⽔果可以⼀⼑切完,纵切就是y相同,左斜切就是x-y相同,右斜切就是x+y相同)。时间:C/C++3秒其他6秒
下⾯是各题做法和思路:
第⼀题:题⽬说的⽐较复杂,读懂题意之后⼤致是,9个字符⼀组,每组的第⼀个字符是标志位,后⾯8个字符是地址。如果标志位是0,地址逆序,标志位是1地址不变。输⼊说明:⼀个字符串,有多组字符,中间没有空格。输出说明:输出最后的地址,每组地址⽤空格隔开,最后⼀个输出不需要空格。
解答:第⼀题很简单,9个⼀组得读取,判断第⼀个是0还是1即可。5分钟内即可AC。
# -*- coding:utf8 -*-
n = int(input())
strs = input()
for i in range(n):
s = strs[9*i:9*i+9] # 9个⼀组得读取
if s[0] == "0":
s = s[1:]
s = s[::-1] # 逆序
else:
s = s[1:]
print(s, end=" ") # 空格输出
第⼆题:简⽽⾔之就是TSP问题。蜂巢在坐标(0,0)的位置,有五处花丛,蜜蜂从蜂巢出发,要把五处花丛的花蜜采完再回到蜂巢,最短距离是多少。输⼊说明:⼀⾏输⼊,10个数分别是五处花丛的坐标(x1,y1,x2,y2,x3,y3,x4,y4,x5,y5),⽤空格隔开。输出说明:输出最短距离,距离向下取整。
解答:⼀开始就想到了全排列之后贪⼼算法取最⼩,虽然觉得⽅法太low了,但是让我⼀下⼦写出蚁之类的觉得记忆模糊就很纠结。后来发现这道题给了10秒的运⾏时间,妥妥的决定⽤全排列了。思路:先⽤全排列的⽅式获取蜜蜂访问5个花丛的所有可能顺序,之后计算每个路径长度取最⼩。
# -*- coding:utf8 -*-
from math import sqrt
line = input().strip().split()
n = list(map(int, line))
n = [int(i) for i in line]
nums = [[0,0], [n[0],n[1]], [n[2],n[3]], [n[4],n[5]], [n[6],n[7]], [n[8],n[9]]] # 以下为插⼊的⽅式获取全排列的代码。没看过别⼈的,⾃⼰想到的。
# 后来看⽹上说,递归获取全排列更常见,有兴趣的可以⾃⼰去搜⼀下。
order = [[1]]
for i in range(2,6):
lens = len(order)
j = 0
while j < lens:
for k in range(i-1):
tmp = order[j][:] #
order.append(tmp)
order[-1].insert(k, i)
order[j].append(i)
j += 1
# 接下来是制作距离矩阵
dist = [[0] * 6 for i in range(6)]
for i in range(6):
for j in range(6):
if dist[i][j] == 0:
dist[i][j] = sqrt((nums[i][0]-nums[j][0])**2 + (nums[i][1]-nums[j][1])**2) else:
dist[i][j] = dist[j][i]
# 贪⼼算法取最⼩
minVal = 0
for path in order:
sums = dist[0][path[0]]
for i in range(4):
sums += dist[path[i]][path[i+1]]
sums += dist[path[4]][0]
if minVal > sums or minVal == 0:
minVal = sumspython和vb的代码可以通用吗
print(int(minVal))
第三题:切⽔果游戏。有⼀个40×50的⽅格,⾥⾯有n(1≤n≤36)个⽔果,每⼀⼑可以横切,竖切以及左斜切与右斜切四种⽅式。想要切完所有⽔果,最少需要多少⼑。输⼊说明:第⼀⾏是说过个数n,接下来的n⾏是⽔果的横纵坐标。输出说明:输出最少需要的⼑数。(PS:原题有图,这⾥⽆图解释⼀下切割⽅式,横切就是所有x相同的⽔果可以⼀⼑切完,纵切就是y相同,左斜切就是x-y相同,右斜切就是x+y相同)。时间:C/C++3秒其他6秒。
解答:当时⽤的贪⼼算法,只通过了70%,后来想到了动态规划算法,虽然没试过但是个⼈感觉应该可以AC。和LeetCode零钱兑换问题差不多的思路。
# -*- coding:utf8 -*-
# 40 * 50的⽅格
from random import randint
# 动态规划算法。对于⼀个点,四种切法去除被切除的点即可获得下⼀次的点集。加上1即可
def dp(points):
if len(points) <= 1:
return len(points)
first = points[0]
row = [i for i in points if i[0] != first[0]]
cntRow = dp(row)
col = [i for i in points if i[1] != first[1]]
cntCol = dp(col)
left = [i for i in points if i[2] != first[2]]
cntLeft = dp(left)
right = [i for i in points if i[3] != first[3]]
cntRight = dp(right)
return 1 + min(cntRow, cntCol, cntLeft, cntRight)
# 贪⼼算法。假设只能选择⼀种⽅式切,选择⼑数最少的
def greedyOne(points):
x = [i[0] for i in points]
y = [i[1] for i in points]
l = [i[2] for i in points]
r = [i[3] for i in points]
return min(len(set(x)), len(set(y)), len(set(l)), len(set(r)))
n = int(input())
points = []
for i in range(n):
line = input().strip().split()
x = int(line[0])
y = int(line[1])
l = y - x
r = x + y
points.append([x, y, l, r])
"""
# 此部分为随机获取点值,确定⾃⼰的动态规划算法是否最优n = 15
for i in range(10):
points = []
for j in range(n):
x = randint(0,40)
y = randint(0,50)
l = y - x
r = x + y
points.append([x, y, l, r])
res1 = dp(points)
res2 = greedyOne(points)
print("dp is %d, greedy is %d"%(res1, res2))
if res1 > res2:
print(points)
"""
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论