华为机试题 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分,就这么没了。
经验
如果碰到提交结果不通过的,可以打印出每个预期的结果,确定是否真的符合预期,如果没问题再下一步。