算法题--华为od机试考试(敏感字段加密、寻找身高相近的小朋友、员工派遣)

目录

敏感字段加密

题目描述

输入描述

输出描述

示例1

输入

输出

示例2

输入

输出

示例3

输入

输出

解析

答案

寻找身高相近的小朋友

题目描述

输入描述

输出描述

示例1

输入

输出

解析

答案

员工派遣

题目描述

问题

输入描述

输出描述

示例1

输入

输出

输入说明

解析

答案


敏感字段加密

考察理解能力、循环、hash。

题目描述

给定一个由多个命令字组成的命令字符串:

1、字符串长度小于等于127字节,只包含大小写字母,数字,下划线和偶数个双引号,

2、命令字之间以一个或多个下划线 进行分割,

3、可以通过两个双引号""来标识包含下划线_的命令字或空命令字(仅包含两个双引号的命令字),双引号不会在命令字内部出现

请对指定索引的敏感字段进行加密,替换为******(6个*),并删除命令字前后多余的下划线_。如果无法找到指定索引的命令字,输出字符串ERROR

输入描述

输入为两行,第一行为命令字索引K(从O开始),第二行为命令字符串S

输出描述

输出处理后的命令字符串,如果无法找到指定索引的命令字,输出字符串ERROR的

示例1

输入

1

password__a12345678_timeout_100

输出

password_******_timeout_100

示例2

输入

1

"password__a12345678"_timeout_100

输出

"password__a12345678"_******_100

示例3

输入

0

"password__a12345678"_timeout_100

输出

******__timeout_100

解析

首先理解一下命令字,当双引号不出现时,命令字一共有通过下划线分割后的单词个数。当双引号出现时,双引号包裹的为一个命令字,

未包裹的通过分割下划线确定个数。

一个一个字符的读取,设置一个标志位,当读到双引号时改变标志位,设置结尾的为双引号,双引号结尾后还原标志位,改为一个下划线结尾。用

对象的key、value存储每次的命令和分割符。key为数字,每次记录加一,value为一个对象存储是否为命令和字符串。最后只需要通过key的数字遍历

找到对应的索引,将value存储的字符串改为******,最后按key从小到大对应的value字符相加。

答案

function getSecrityStr(str) {
    let [n, target] = str.split('\n')
    let len = target.length
    let sign = true
    let i = 0
    let tmp = ''
    let obj = {}
    let j = 0
    while (i < len) {
        // 下划线为结尾
        if (sign) {
            // 当为双引号时改变标志位,判断命令结尾为双引号
            if (target[i] === '"') {
                tmp = tmp + target[i]
                sign = false
                // 已经记录了一段命令字符后结尾  
            } else if (target[i] === '_' && tmp.length) {
                obj[j] = {
                    value: tmp,
                    order: true
                }
                j++
                obj[j] = {
                    value: '_',
                    order: false
                }
                j++
                tmp = ''
                // 结尾有多个下划线  
            } else if (target[i] === '_' && !tmp.length) {
                // 判断是否为引号后的情况  
                if (obj[j - 1].value.endsWith('_')) {
                    obj[j - 1].value = obj[j - 1].value + '_'
                } else {
                    obj[j] = {
                        value: '_',
                        order: false
                    }
                    j++
                }
            } else {
                tmp = tmp + target[i]
            }
        } else {
            // 双引号为结尾
            if (target[i] === '"') {
                tmp = tmp + target[i]
                obj[j] = {
                    value: tmp,
                    order: true
                }
                sign = true
                j++
                tmp = ''
            } else {
                tmp = tmp + target[i]
            }
        }
        i++
    }
    if (tmp !== '') {
        obj[j] = {
            value: tmp,
            order: true
        }
    }
    let hasRes = false
    let m = 0
    for (let i = 0; i <= j; i++) {
        if (obj[i].order) {
            m++
        }
        // 找到目标为索引的命令
        if (m - 1 === Number(n)) {
            obj[i].value = '******'
            // 将目标前后的下划线变为一个
            if (obj[i + 1]) {
                obj[i + 1].value = '_'
            }
            // 将目标前后的下划线变为一个
            if (obj[i - 1]) {
                obj[i - 1].value = '_'
            }
            hasRes = true
            break
        }
    }
    let res = ''
    for (let i = 0; i <= j; i++) {
        res = res + obj[i].value
    }
    if (hasRes) {
        return res
    }
    return 'ERROR'
}
console.log(getSecrityStr(`1
password__a12345678_timeout_100`))
console.log(getSecrityStr(`1
"password__a12345678"_timeout_100`))
console.log(getSecrityStr(`0
"password__a12345678"_timeout_100`))

寻找身高相近的小朋友

考察多优先级排序

题目描述

小明今年升学到了小学1年级来到新班级后,发现其他小朋友身高参差不齐,然后就想基于各小朋友和自己的身高差,对他们进行排序,请帮他实现排序。

输入描述

第一行为正整数 h和n,0<h<200 为小明的身高,0<n<50 为新班级其他小朋友个数。

第二行为n个正整数,h1 ~ hn分别是其他小朋友的身高,取值范围0<hi<200,且n个正整数各不相同。

输出描述

输出排序结果,各正整数以空格分割,

和小明身高差绝对值最小的小朋友排在前面,

和小明身高差绝对值最大的小朋友排在后面,

如果两个小朋友和小明身高差一样,则个子较小的小朋友排在前面。

示例1

输入

100 10

95 96 97 98 99 101 102 103 104 105

输出

99 101 98 102 97 103 96 104 95 105

解析

通过sort函数,先按从小到大排序,再按和目标值差的绝对值从小到大进行排序。这样相当于排序优先级第一位为目标值差的绝对值大小,第二位的为数值大小。

答案

function absSort(str) {
    let arr = str.split('\n')
    let [base, len] = arr[0].split(' ')
    arr = arr[1].split(' ').map(Number)
    arr.sort((a, b) => a - b).sort((a, b) => Math.abs(a - base) - Math.abs(b - base))
    return arr.join(' ')
}
console.log(absSort(`100 10
95 96 97 98 99 101 102 103 104 105`))

员工派遣

考察二分法

题目描述

某公司部门需要派遣员工去国外做项目。现在,代号为x的国家和代号为y的国家分别需要cntx名和cnty名员工。部门每个员工有一

个员工号(1,2,3....),工号连续,从1开始。

部长派遣员工的规则:

规则1、从[1,K]中选择员工派遣出去

规则2、编号为x的倍数的员工不能去x国,编号为y的倍数的员工不能去y国

问题

找到最小的k,使得可以将编号在[1,K]中的员工分配给x国和y国,且满足x国和y国的需求

输入描述

四个整数x,y,cntx,cnty。(2<=x<y<=30000;x和y一定是质数;1<=cntx,cnty<10^9; cntx-cnty<=10^9)

输出描述

满足多件的最小的k。

示例1

输入

2 3 3 1

输出

5

输入说明

2表示国家代号2

3表示国家代号3

3表示国家2需要3个人

1表示国家3更要1个人

解析

这里注意输入描述cntx,cnty的要求小于10^9,说明输入数据比较大,所以不能直接通过循环一个一个判断。

所以这里需要采用二分法去求解,当总数为n时,不能去往x国家的人数有n/x向下取整,即可以去往x国的人数为n-Math.floor(n/x)。同理可以

得出可以去往y国的人数,当都满足要求时把right = mid-1,当有一个不满足要求时把left = mid + 1,最后当left>right时跳出循环返回right+1即可。

答案

function dispatchNum(str) {
    let [x, y, cntx, cnty] = str.split(' ').map(Number)
    let left = 0
    let right = Math.pow(10, 9)
    let meet_x = 0
    let meet_y = 0
    while (left <= right) {
        mid = left + Math.floor((right - left) / 2)
        // 满足条件的x的个数
        meet_x = mid - Math.floor(mid / x)
        // 满足条件的y的个数
        meet_y = mid - Math.floor(mid / y)
        if (cntx <= meet_x && cnty <= meet_y) {
            right = mid - 1
        } else {
            left = mid + 1
        }
    }
    return right + 1
}
console.log(dispatchNum(`2 3 3 1`))

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值