刷题去WLB965 客户输入密码的时间是多少?

ww15510313428 · September 01, 2020 · Last by fungaegis replied at September 15, 2020 · Last modified by admin 恒温 · 6834 hits
本帖已被设为精华帖!

编程题求解:
为了防止被黑客获取到客户输入的密码,某银行在登录软件上以屏幕输入法输入密码。
该输入法有9个按钮,每个按钮上有不多于3个字母。字母有先后顺序。
按第一个字母需要用鼠标点击按钮一次, 第二个字母需要点击2次,
第三个字母需要点击3次,若连续两个字母都在同一个按钮上,则输入第一个字母后需要等待一小段时间。
假设某客户的输入习惯是:点击按钮需要1单位时间,等待一小段时间为2单位时间,某次登录的时候,
9个按钮上的字母分别为azc dwf gti jql mon pkr shu vex yb,求该客户输入他的密码的时间 。
输入:
该客户的密码都是小写字母[a-z],密码长度<=16
输出:
客户输入密码的时间。

最佳回复

Python2.7解题代码宣判封顶,此贴终结。

keyboard = list("azcdwfgtijqlmonpkrshuvexyb")
time_delta = 1

def get_wait_time(c, b):
return int(2 * time_delta) if max(keyboard.index(c), keyboard.index(b)) <= (min(keyboard.index(c), keyboard.index(b))/3*3 + 2) else 0


def test(input_str):
# 所有字符的输入时间统计
char_time = sum([(keyboard.index(c)% 3 + 1) * time_delta for c in list(input_str)])
# 同一按键等待时间统计
wait_time = sum([get_wait_time(c, list(input_str)[index-1]) for index, c in enumerate(list(input_str)) if index >= 1])
print sum([char_time, wait_time])

test(input())

题目最核心的就是如何完成重复按键的检查,所以看懂max(keyboard.index(c), keyboard.index(b)) <= (min(keyboard.index(c), keyboard.index(b))/3*3 + 2)这个就行啦,⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄

分享一下我的重复按键检测的判断思路哈:

  • 把键盘的所有按键转化成一个list,如源码中的keyboard变量 [a,b,c,d,e,f...]
  • 找到两次连续按键对应的键盘索引值
  • 用两个值当中的最小值 除以3 之后再乘以3,就可以得到该按键所在区间的起始位置(这里你得把keyboard想像成[a,b,c],[d,e,f]这种二维数组),因为每个按键的起始位置索引是有规律的,0/3/6/9...
  • 得到起始位置之后,是否连续只要看更大的那个索引值和起始位置相差是否超过2即可
  • 巴拉巴拉...
# 自测一哈
test("a") # 预期结果1
test("azc") # 预期结果:按键时间a1,z2,c3 = 6,等待2+2=4 10
test("adw") # 预期结果:按键时间a1,d1,w2 = 4,等待2, 6
test("acd") # 预期结果:按键时间a1,c3,d1 = 5,等待2,总7

欢迎小伙伴们测试找bug _^ (本来想写在一行的,感觉装逼会被人打:)手动狗头)

共收到 28 条回复 时间 点赞
ww15510313428 关闭了讨论 01 Sep 17:50
ww15510313428 重新开启了讨论 01 Sep 17:50

这是应用题。。。

就是搞几个变量记下状态 遍历输入算时间啊
记下上次输入在9键中哪一个,判断下是否连续;记一下目前是第几位密码 然后就顺着算

恒温 回复

嗯,我现在就是卡在了不知道如何判断连续输入的字符是不是在同一个按键上

那这个公司破产了,什么样的沙雕才会出这样的需求,毫无用户体验,客户直接没了

点击一次的a d g m p s v y
点击两次的z w t q o k h e b
点击三次的c f i l n r u x
同一按键的azc dwf gti jql mon pkr shu vex yb
同一按键等待2个单位,其他就是点几次加起来就行。。。。这个题确实是小学应用题,哈哈

8Floor has been deleted
恒温 回复

testerhome系统字体都变繁体了吗,还是一直都是繁体,而我才刚发现😂

你设置了locale了?

恒温 回复

我把社区的网站清除了缓存,重新进来好了,不知道是不是啥时候误点了哪里,哈哈。

这道题两个月前刚做过,我大概知道作者是去了哪个公司的碰到了笔试题😂

ww15510313428 关闭了讨论 02 Sep 17:07
ww15510313428 重新开启了讨论 02 Sep 17:07

回来越想越不对劲,虽然当时没写出来,想着下次在遇到不能还不会吧😂

每次刷新出来的字母应该是乱序的,所以不存在某个字母永远只需要点击一次的问题。
应该是个开放性的问题,观察面试者思考问题是否全面。
”每次刷新出来的字母应该是乱序的,所以不存在某个字母永远只需要点击一次的问题。“ 譬如这句话是我自己的经验告诉我的,所以需要和面试官确认。
把所有的细节确认完毕之后在做题。

当然了,如果这个直接就是给你做的题目,没有面试在你面前,这样的公司,不去也罢啊(傲娇)

ww15510313428 回复

有没有解法?

victor 回复

抛开面试,回归到问题,不是为了通过题来判断公司如何,核心问题是这道题如何解

恒温 回复

用了个笨办法,应该有更好的解法


public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNext()) {
String inputStr = scanner.nextLine();
System.out.println(inputStr);
char[] strs = inputStr.toCharArray();
getTimes(strs);
}
}

public static int getTimes(char[] strs) {
int times = 0;
//记录每个按键的单位时间
Map < String, Integer > values = new HashMap<String, Integer>();
values.put("a", 1);
values.put("d", 1);
values.put("g", 1);
values.put("j", 1);
values.put("m", 1);
values.put("p", 1);
values.put("s", 1);
values.put("v", 1);
values.put("y", 1);
values.put("z", 2);
values.put("w", 2);
values.put("t", 2);
values.put("q", 2);
values.put("o", 2);
values.put("k", 2);
values.put("h", 2);
values.put("e", 2);
values.put("b", 2);
values.put("c", 3);
values.put("f", 3);
values.put("i", 3);
values.put("l", 3);
values.put("n", 3);
values.put("r", 3);
values.put("u", 3);
values.put("x", 3);
//记录每个字母的按键位置
Map < String, Integer > keys = new HashMap<String, Integer>();
keys.put("a", 1);
keys.put("d", 2);
keys.put("g", 3);
keys.put("j", 4);
keys.put("m", 5);
keys.put("p", 6);
keys.put("s", 7);
keys.put("v", 8);
keys.put("y", 9);
keys.put("z", 1);
keys.put("w", 2);
keys.put("t", 3);
keys.put("q", 4);
keys.put("o", 5);
keys.put("k", 6);
keys.put("h", 7);
keys.put("e", 8);
keys.put("b", 9);
keys.put("c", 1);
keys.put("f", 2);
keys.put("i", 3);
keys.put("l", 4);
keys.put("n", 5);
keys.put("r", 6);
keys.put("u", 7);
keys.put("x", 8);
for (int i = 0; i < strs.length; i++) {
String c = String.valueOf(strs[i]);
int time = values.get(c);
int key = keys.get(c);//记录当前字母的按键数
if (i == 0) {
times = times + time;
continue;
}
//取当前字母的前一个字母
String cc = String.valueOf(strs[i - 1]);
int bkey = keys.get(cc);
if (bkey == key) {//同一个按键上
times = times + 2;
}
times = times + time;
}
return times;
}
#!/usr/bin/env python
# encoding: utf-8
password=input('请输入密码:')
b_hold=1
b_wait=2
b_total=b_hold+b_wait
str1=['azc','dwf','gti','jql','mon','pkr','shu','vex','yb']
p_len=len(password)
p_total=p_len
time1=b_hold
while (p_len-1):
flag=0
for i in str1:
if (password[p_total-p_len] in i) and (password[p_total-p_len+1] in i):
flag=1
break
if flag:
time1 += b_total
else:
time1+=b_hold
p_len-=1
print(time1)

Python2.7解题代码宣判封顶,此贴终结。

keyboard = list("azcdwfgtijqlmonpkrshuvexyb")
time_delta = 1

def get_wait_time(c, b):
return int(2 * time_delta) if max(keyboard.index(c), keyboard.index(b)) <= (min(keyboard.index(c), keyboard.index(b))/3*3 + 2) else 0


def test(input_str):
# 所有字符的输入时间统计
char_time = sum([(keyboard.index(c)% 3 + 1) * time_delta for c in list(input_str)])
# 同一按键等待时间统计
wait_time = sum([get_wait_time(c, list(input_str)[index-1]) for index, c in enumerate(list(input_str)) if index >= 1])
print sum([char_time, wait_time])

test(input())

题目最核心的就是如何完成重复按键的检查,所以看懂max(keyboard.index(c), keyboard.index(b)) <= (min(keyboard.index(c), keyboard.index(b))/3*3 + 2)这个就行啦,⁄(⁄ ⁄•⁄ω⁄•⁄ ⁄)⁄

分享一下我的重复按键检测的判断思路哈:

  • 把键盘的所有按键转化成一个list,如源码中的keyboard变量 [a,b,c,d,e,f...]
  • 找到两次连续按键对应的键盘索引值
  • 用两个值当中的最小值 除以3 之后再乘以3,就可以得到该按键所在区间的起始位置(这里你得把keyboard想像成[a,b,c],[d,e,f]这种二维数组),因为每个按键的起始位置索引是有规律的,0/3/6/9...
  • 得到起始位置之后,是否连续只要看更大的那个索引值和起始位置相差是否超过2即可
  • 巴拉巴拉...
# 自测一哈
test("a") # 预期结果1
test("azc") # 预期结果:按键时间a1,z2,c3 = 6,等待2+2=4 10
test("adw") # 预期结果:按键时间a1,d1,w2 = 4,等待2, 6
test("acd") # 预期结果:按键时间a1,c3,d1 = 5,等待2,总7

欢迎小伙伴们测试找bug _^ (本来想写在一行的,感觉装逼会被人打:)手动狗头)

21Floor has been deleted
word = ('abc', 'dwf', 'gti', 'jql', 'mon', 'pkr', 'shu', 'vex', 'yb')
time = 0
temp_button = ''


def inputTime(a):
"""计算非同一按钮连续输入的单次输入时间"""
global time
for button in word:
if a in button:
time += button.index(a) + 1
return time
continue


def isSameButton(a, b):
"""判断是否为同一按钮连续输入"""
global temp_button
for button in word:
if a in button:
if b in button:
temp_button = button
return True
return False
continue


password = str(input('请输入密码'))
# 默认输入的是小写字母
for i in range(len(password)):
if i == 0:
inputTime(password[i])
else:
if isSameButton(password[i-1], password[i]):
time = time + 3 + temp_button.index(password[i])
else:
inputTime(password[i])
print(time)
23Floor has been deleted
keys = ["azc", "dwf", "gti", "jql", "mon", "pkr", "shu", "vex", "yb"]
password = "awdsdasd"
time = 0
before_word = '+' # 前一位密码,初始用+替代,以免误判
for word in password:
for key in keys:
if word in key:
time += key.index(word)+1 # 密码在这个键盘的下标+1(下标0开始)
if before_word in key: # 前一位密码是否和当前密码在同一个键位上,是就+2
time += 2
before_word = key
break
print(time)

没用啥算法,效率可能比较低

25Floor has been deleted

😅 这么科学的答案木有赞,要报警了=、=

感觉这个社区不简单,藏龙卧虎,以后要经常来

恒温 将本帖设为了精华贴 04 Sep 15:42

BUG就是。。。输入的密码没有做类型校验和长度校验😁

看了半小时才弄明白答案的我是不是已经凉透了 😅 😅

leixs 回复

😅 可能是我写的不够清楚...

我有个问题 我的理解是 这种输入方式跟 9宫格输入法 输入字母时一样. 按楼主给的键盘位 9个按钮上的字母分别为azc dwf gti jql mon pkr shu vex yb 假如输入 cd的话应该是 c=3 d=1 结果为4 按你代码的计算 max=3 min=4 得出答案为6...........

34Floor has been deleted
fungaegis 回复

不对呀,c的索引是2,d的索引是3呀…
Max是3,min是2哟…
在路上,手机看的晕乎乎😹

我的意思是 c=3个单位 d=1个单位 中间不存在等待 所以为4个单位
如果按照你的代码思路:

c_index = 2, d_index = 3
max(2, 3) # 3
(min(2, 3)/3*3+2) # 4

所以会出现等待时间2个单位

fungaegis 回复
>>> min(2,3)/3*3 +2
2

计算出来是2,不是4噢,想框我没门😆

我知道什么情况了, 2+ /是地板除 3+//才是地板除 我的锅

需要 Sign In 后方可回复, 如果你还没有账号请点击这里 Sign Up