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

ww15510313428 · 2020年09月01日 · 最后由 sleepyhead 回复于 2020年12月09日 · 388 次阅读
本帖已被设为精华帖!

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

最佳回复
共收到 30 条回复 时间 点赞
ww15510313428 关闭了讨论 09月01日 09:50
ww15510313428 重新开启了讨论 09月01日 09: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 个单位,其他就是点几次加起来就行。。。。这个题确实是小学应用题,哈哈

8楼 已删除
恒温 回复

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

你设置了 locale 了?

恒温 回复

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

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

ww15510313428 关闭了讨论 09月02日 09:07
ww15510313428 重新开启了讨论 09月02日 09: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)
21楼 已删除
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)
23楼 已删除
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)

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

25楼 已删除
高手 回复

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

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

恒温 将本帖设为了精华贴 09月04日 07: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...........

34楼 已删除
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+//才是地板除 我的锅

39楼 已删除
仅楼主可见
41楼 已删除

public static int inputTime(String psw){ //健壮性判断略。。。

//将九宫格切割个九个字符串数组 String s = "azc dwf gti jql mon pkr shu vex yb"; String[] ss = s.split(" "); //第一个字母时间为 1 int time = 1; for(int i=0;i<psw.length()-1;i++){ //循环遍历密码的相邻两位 String twoStr = psw.substring(i,i+2); //根据第一个字符字母拿到所在子串,判断第二个字母是否在子串, boolean b = containsStr(ss, twoStr.substring(0,1),twoStr.substring(1,2)); //返回 true:+2,返回 false:+1 time+=b?2:1; } return time; }

public static boolean containsStr(String[] ss,String ch1,String ch2){ for(String str:ss){ if(str.contains(ch1)){ return str.contains(ch2); } } return false; }

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册