2017 携程 笔试编程题 1

前言

今天参加了携程的笔试,编程题第一题一开始想错了方向,花费了很多时间(虽然第二题就是给时间也不一定做得出来,(⊙﹏⊙)b)。

下面记录一下这个小插曲。

正文

题目要求

将指定的正整数n分解成若干个互不相同的自然数的和,且使这些自然数的乘积最大
  • 1

人家给了个输入输出的例子,如下:

输入15
  • 1
输出 144
  • 1

言下之意就是在自然数之和为15的这些数字中,乘积最大的一对是

2 3 4 6
  • 1

思路

为了使得这些自然数之和的乘积最大,那么这些数字应该尽可能的接近。

下面举几个小例子:

n=10

2+3+4 = 9
// 剩下的那个1补到4上面
2+3+5 
  • 1
  • 2
  • 3

这个时候最大的乘积变成了30

n = 18

2+3+4+5 = 14
//按照刚才的思路, 剩下的4 添加到5上面
2+3+4+9
  • 1
  • 2
  • 3

此时最大的乘积结果为216

那么这时的结果是最大的吗?

答案是否定的,因为刚才是从下标为2开始的。如果下标从3,从4开始呢,我们来看下效果。

3+4+5+6 -->> 最大结果为:360
  • 1
4+5+6+7>18则进行去尾加和
4+5+9  -->> 最大结果为: 180
  • 1
  • 2

剩下的其实就不用考虑了。

核心

经过刚才的铺垫,这下不难理解了。最笨的方法就是不断的递增下标,然后记录每一个下标对应的最大值。存储起来,然后找到这些最大值中最大的那个,就是我们要求的结果了。

代码如下:

def mutl(ls):
    result = 1
    for item in ls:
        result *= item
    return result

def compute(n, step):
    path = []
    cursum = 0
    for index in range(step, n):
        if cursum > n:
            last = path.pop()
            path.append(path.pop() + n - (cursum - last))
            break
        path.append(index)
        cursum += index
    return mutl(path)

def my(n):
    total = []
    maxvalue = 0
    for step in range(int(n/2)):
        item = compute(n, step)
        total.append(item)
    maxvalue = max(total)
    return maxvalue



n = 15
result= my(n)
print(result)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32

运行结果:

144
  • 1

测试

再来多测几组数据。

  • n=10
30
  • 1
  • n=18
360
  • 1

这下,可以啦。需要注意的是:

递增下标到n的一半的位置就可以了,否则结果会不正确,这是因为计算每次的step的时候会把第一个给算进去,所以导致结果偏大。

总结

就携程的笔试题而言,前面部分的问答题和选择题还算是中规中矩,比较偏重于理论和实践。

编程题就真的是考验算法的了。大部分的笔试题都是动态规划类型的。我本人比较偏重于开发方向,所以参加这种笔试题真的是有点力不从心。

不管怎么说,算法是很有必要的。多学点,肯定没错,说不一定以后就用得到了。

我, 还有很长的路要走啊。

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

猜你喜欢

转载自www.cnblogs.com/djuwcnhwbx/p/10325622.html