华为机试题 2022-05-22

三道笔试题,都是coding, 第一题简单,第二三题难度都在中等范围。

1 最大非严格递增数字序列

题目描述
输入一个字符串仅包含大小写字母和数字,求字符串中包含的最长的非严格递增连续数字序列的长度(比如12234属于非严格递增连续数字序列)。
输入描述:
输入一个字符串仅包含大小写字母和数字,输入的字符串最大不超过255个字符。

思路 拆分出来所有的数字序列,然后逐个计算最大有效长度,选择最大的一个输出即可。

function s1() {
    let str = readline()
    let list = str.split(/[a-zA-z]+/)

    let arr = [], sum = 0, max = 0
    for (let i =0; i< list.length; i++) {
        arr = []
        if(list[i].length > 0) {
            sum = 1
            arr = list[i].split('').map(item => parseInt(item))

            for (let j =0; j < arr.length-1; j++) {
                if(arr[j+1] < arr[j]) {
                    max = Math.max(max, sum)
                    sum = 1
                }else {
                    sum++
                }
            }
            // 循环结束后 再获取一下
            max = Math.max(max, sum)
        }
    }
    print(max)
}

2 计算绘图面积

绘图机器的绘图笔初始位置在原点(0,0),机器启动后其绘图笔按下面规则绘制直线:
1)尝试沿着横向坐标轴正向绘制直线,直到给定的终点值E。
2)期间可通过指令在纵坐标轴方向进行偏移,并同时绘制直线,偏移后按规则1绘制直线;指令的格式为× offsetY,表示在横坐标X沿纵坐标方向偏移,offsetY为正数表示正向偏移,为负数表示负向偏移。
给定了横坐标终点值E、以及若干条绘制指令,请计算绘制的直线和横坐标轴、以及X=E的直线组成图形的面积。
输入描述:
首行为两个整数NE,表示有N条指令,机器运行的横坐标终点值E。
接下来N行,每行两个整数表示一条绘制指令x
offsetr,用例保证横坐标x以递增排序方式出现,且不会出现相同横坐标x。
取值范围: 0<N<= 10000,0 <= x<=E<=20000,-10000<=offsetr <= 10000。
输出描述:
一个整数,表示计算得到的面积,用例保证,结果范围在0~4294967295内

思路 计算面积需要知道宽高,宽就是两次指令的X差值,高就是前面offsetY的累加和,最后再将E值和最后一条指令求差值。 两个指令之间就可以得到前一个指令的面积了,累计起来即可。

function s2(){
    let row1 = readline().trim().split(' ')
    let N = parseInt(row1[0]), E = parseInt(row1[1])
    let list = [], sum = 0, L = 0, last = 0

    for (let i = 0; i < N; i++) {
        let a = readline().split(' ')
        let one =  parseInt( a[0] )
        // 当前x坐标对应y值
        sum += parseInt( a[1] ) 
        // 指令横坐标差距
        if (i == N-1) {
            last = one
        } 
        L = one - L
        list.push( [ L, sum ] ) 
        L = one

    }
    let s = 0
    for (let i = 1; i <= list.length; i++) {
        if (i == list.length) {
            s += Math.abs(list[i-1][1] * (E - last))
        }else {
            s += Math.abs(list[i-1][1] * list[i][0])
        }
    }

    print(s)
}

3 最大吃菜量

入职后,导师会请你吃饭,你选择了火锅。火锅里会在不同时间下很多菜。
不同食材要煮不同的时间,才能变得刚好合适。你希望吃到最多的刚好合适的菜,但是你的手速不够快,用m代表手速,每次下手捞菜后至少要过m秒才能再捞(每次只能捞一个)。那么用最合理的策略,最多能吃到多少刚好合适的菜?
输入描述:
第一行两个整数n,m,其中n代表往锅里下的菜的个数,m代表手速。
接下来有n行,每行有两个数x,y代表第x秒下的菜过y秒才能变得刚好合适。
(1 < n,m < 1000)(1 <x,y<1000)
输出描述:
输出一个整数代表用最合理的策略,最多能吃到刚好合适的菜的数量

思路 先将所有的菜的“刚好合适”时间计算出来,存到list数组里,然后排个序。刚好合适时间就是 x+y 。然后第一个菜不需要等m秒就直接捞。第二个开始计算与前一次捞的时间是否大于等于m秒,是则表示又可以捞了,不是则舍弃,看下一个。这最终的结果就是 最多吃到的菜数量。一个简单的动态规划。

function s3() {
    let row1 = readline().split(' ')
    var n = parseInt(row1[0]), m = parseInt(row1[1])

    let list = []
    for (let i = 0; i < n; i++) {
        let a = readline().split(' ')
        list.push( parseInt(a[1]) + parseInt(a[0]))
    }
    list.sort()
    // 初始条件
    let index = 1, L = list[0], max = n < 1 ? 0 : 1
    while (index < list.length) {
        if (list[index] -L < m){
            index++
        } else {
            L = list[index]
            index++
            max++
        }
    }
    print(max)
}

总结
我做题的顺序是3-2-1,(分值:200,100,100),2、3都通过。

第3题没有通过,考试的时候发现 测试用例都通过,随机选择的数据测试也符合预期值,就是提交后通过率 0%。
下来之后思考为什么出现这个问题,于是打印每个选择的菜的下标,才发现与预期的不符合,没有第一个刚好合适的菜。于是发现我的“初始条件”搞错了。
我一开始的初始条件代码如下:

let index = 0, L = 0, max = 0

实际应该是这样,第一个必选。

let index = 1, L = list[0], max = n < 1 ? 0 : 1

考试的时候是这么想的,可能是因为循环初始条件为0写习惯了,后来又因为测试用例通过,导致我陷入了其他的纠结之中。
我线下第一时间就想到了打印出每个选中的菜的下标,一下就找到问题的根源了。害, 还是不够细心呐~ 这第3题可是200分,就这么没了。

经验
如果碰到提交结果不通过的,可以打印出每个预期的结果,确定是否真的符合预期,如果没问题再下一步。

有问题反馈加微信:mue233 私聊问我 微信公众号:焦虑自愈教程,分享过去走出来的经验
52软件资源库 » 华为机试题 2022-05-22