网易有道2020测试开发工程师校招编程题

简答-10分-水仙花数

输出100到1000内的水仙花数。水仙花数的定义是某个三位数,它个位数的三次方加上十位数的三次方加上百位数的三次方之和等于这个数。

def solution():
	for i in range(100,1001):
		a = i//100
		b = i%100//10
		c = i%10
		if i == a**3 + b**3 + c**3:
			print(i,end=' ')
solution()

编程题第一题-20分

问题描述:

S(n)为n的各位数字之和。给定一个x,求出最小的正整数n,使得x<=S(n)。

样例输入:

9
13

样例输出:

9
49

问题分析:

这题引入了个S(n),妈的劳资最烦数学符号了。
其实题目并不难,就是求某个数的各位之和等于x。这个数最小。
根据常识,应该使高位数字小,低位数字大。那么低位数字最大是9,所以从右往前遍历即可。

AC代码:

def solution():
    t = int(input())
    for i in range(t):
        cur = int(input())
        res = ''
        while cur > 9:
            res = '9' + res
            cur -= 9
        res = str(cur) + res
        print(res)

solution()

第二题-吃葡萄-20分

这题很多大佬饮恨。当然啦我这个渣渣也饮恨了。(最后想出来了,没调通,好气哦,还是代码能力差。不然的话可以调通的。多加练习。庆幸的是我是21届)。所以说笔试题之前要调整好状态,别困的跟个傻逼一样就去做,不然很容易饮恨的。(比如我)
问题描述:

有3种葡萄,数量分别是a,b,c。 第一个人只吃1,2种葡萄,第二个人只吃2,3种葡萄,第三个人只吃1,3种葡萄。
问怎么安排让3人吃完所有的葡萄,而且让吃的比较多的那个人吃的葡萄尽可能的少。

问题分析:

这题的3种葡萄和第几个人吃第几种葡萄完全是忽悠人的,因为无论谁先吃谁后吃,无论哪种葡萄多哪种葡萄少,每一种葡萄都可以被两个人吃,而且一个人可以吃两种葡萄。
并且,想让吃的最多的人吃的尽量少,这就要求吃的最少的人吃的尽量多。
仔细思索我们就会发现,如果较少的两堆葡萄足够某个人吃(即两堆葡萄之和大于等于总数的1/3),那么3个人可以平均分这些葡萄(当然啦,如果葡萄不能整除3,就再加上1,为啥?因为别管是多1个葡萄还是多2个葡萄,都得+1(被一人吃和被两人吃,没区别))。
如果较少的两堆葡萄还不够某个人吃(那也不能再吃啦,因为一人只能吃两种葡萄),那么最大值就等于最多的那堆葡萄除以2,如果最大值是奇数,还得再加1.(因为肯定会有一人多吃一人少吃)

AC代码:

def solution():
    t = int(input())
    for i in range(t):
        data = list(map(lambda x: int(x), input().split()))
        data.sort()
        a,b,c = data
        avg = sum(data)//3 # 直接//3即可
        '''
        因为如果能整除,那么答案肯定是1/3
        如果不能整除,答案肯定是1/3+1 怎么都无妨
        '''
        if a+b >= avg:
            remains = sum(data)-avg
        else:
            remains = data[-1]
        if remains%2:
            res = remains//2 + 1
        else:
            res = remains//2
        print(res)

solution()

第三题-漂亮数-20分

问题描述

对于一列数来讲,如果第i个数不小于前面i-1个数的和,那么称之为漂亮的数。 求一串数中最长的漂亮的数段。

解析

这题用在线处理很方便,O(n)的时间就能搞定。可当做是最大子段和的变种题目。只不过这里要存储当前的和,比最大子段和要稍微麻烦一丢丢。其实就是多一个变量的事儿。

AC代码:

def solution():
    t = int(input())
    for i in range(t):
        n = int(input())
        data = list(map(lambda x:int(x),input().split()))
        maxs = 1
        curs = 1
        pre_sums = data[0]
        for dj in range(1,n):
            if data[dj] >= pre_sums:
                curs += 1
                pre_sums += data[dj]
            else:
                if curs > maxs:
                    maxs = curs
                curs = 1
                pre_sums = data[dj]
        if curs > maxs:
            maxs = curs
        print(maxs)
solution()

第四题-势均力敌-20分

问题描述

给定一个数组,假定这个数组是一个环,问能不能把这个环分成两个连续的部分,使他们的值相等。

思路:

这题跟上面那个在线处理算法非常的像。不太明白网易想get的点在哪里。只不过这个是一个环,要用到循环队列的思想。(当然这是考试,只需要模拟循环队列即可)。
如果整个数组的和不是2的倍数,那么肯定不行。 如果是2的倍数,那么就用在线处理找出等于和的一半的序列。
注意,退出的条件肯定是找了一圈还没找到(因为题目是一个环,如果不设置退出条件可能会死循环),即比如head是0,找了一圈head又回到了0,那肯定是没找到的。而且要注意什么时候应该拐弯(毕竟是一个环嘛)

AC代码:

def solution():
    t = int(input())
    for i in range(t):
        n = int(input())
        data = list(map(lambda x:int(x),input().split()))
        sums = sum(data)
        if sums%2:
            print('NO')
            continue
        sums //= 2
        head = tail = 0
        flag = True # flag指示是不是绕了一圈了
        cur_sum = data[0]
        while cur_sum != sums:
            if head == 0 and not flag: # 重复查找
                break
            if cur_sum < sums: # 如果小,就纳入新的
                if tail == n - 1:
                    tail = 0
                else:
                    tail += 1
                cur_sum += data[tail]
            if cur_sum > sums: # 如果大于,就减去老的
                cur_sum -= data[head]
                if head == n-1:
                    head = 0
                else:
                    head += 1
                    if head == 1:
                        flag = False
        if cur_sum == sums:
            print('YES')
        else:
            print('NO')
solution()

你可能感兴趣的:(校招笔试题)