测开笔试题
某厂笔试题:
执行时限1000ms
一个典型的电话拨号盘如下:
1 2 3
4 5 6
7 8 9
** 0 #
手指在两个按键之间的移动距离被定义为这两个键的x、y坐标差的绝对值之和。
比如:6到自身的距离是0,到3、5、9键的距离是1,到2、4、8、#键的距离是2,
到1、7、0键的距离是3,到*键的距离是4。
现在要你算一下:拨打一个电话号码手指所需要移动的最小距离是多少?
假设,手指的初始位置是在“5”键上。
输入:
一行,一个字符串,表示需要拨打的电话号码。
输入约束:
电话号码的每一位仅包含数字0到9,且总长度范围是[3,20]
输出:
一个整数,表示拨完整个号码,手指所需要移动的最小距离。
例子:输入 911
输出 6
解题过程:
例子分析: 输入911,手指经过的键是5–>9–>1–>1,其中5–>9的最小距离是2,9–>1的最小距离是4,1–>1的最小距离是0,因此结果是2+4+0=6。
算法:
1、初始化一个电话盘一样的二维列表;
2、根据二维列表,生成一个字典,电话盘中的每个键值是key,
键值在二维列表中的坐标[x轴,y轴]是value;
3、遍历电话号码:计算当前键的位置,与上一个键的距离。
距离=绝对值之和=abs(上一个键的横坐标-当前键的横坐标)+abs(上一个键的纵坐标-当前键的纵坐标)
4、将所有电话号码之间的距离进行累加,并返回结果。(初始位置是5键,坐标是【1,1】)。
将算法翻译成代码:
arr =[[1,2,3],[4,5,6],[7,8,9],["*",0,"#"]]
d = {}
# 两层for循环,生成字典,key是电话盘上的数字,value是各数字的二维坐标
for i in range(len(arr)):
for j in range(len(arr[i])):
d[arr[i][j]] = [i,j]
"""
print(d)
d={1: [0, 0], 2: [0, 1], 3: [0, 2], 4: [1, 0], 5: [1, 1], 6: [1, 2],
7: [2, 0], 8: [2, 1], 9: [2, 2], '*': [3, 0], 0: [3, 1], '#': [3, 2]}
"""
def get_distance():
tel = input("请输入电话号码:")
if len(tel) < 3 or len(tel) > 20:
raise Exception("电话号码长度非法")
try:
int(tel)
except Exception as e:
print("输入的电话不是纯数字")
print(e)
else:
result = 0
start = [1, 1]
for i in tel:
# d[int(i)]指的是当前电话数字对应的坐标,那么d[int(i)][0] 即横坐标
sum_x = abs(start[0] -d[int(i)][0])
# 同理d[int(i)][1] 即当前电话数字的纵坐标
sum_y = abs(start[1] -d[int(i)][1])
result += sum_x + sum_y
# 每一个号码循环完后,要把初始位置改为当前数字的坐标,方便下一轮的循环
start = d[int(i)]
return result
if __name__ == "__main__":
# 自测6次
for i in range(6):
get_distance()
"""
测试结果如下:
请输入电话号码:911
6
请输入电话号码:123456
9
请输入电话号码:643247
10
请输入电话号码:8606335540
16
请输入电话号码:8606574276
21
请输入电话号码:dsfsf
输入的电话不是纯数字
"""