【刷题】美团笔试训练

美团点评2017秋招笔试编程题

试题链接

1. 大富翁游戏

大富翁游戏,玩家根据骰子的点数决定走的步数,即骰子点数为1时可以走一步,点数为2时可以走两步,点数为n时可以走n步。求玩家走到第n步(n<=骰子最大点数且是方法的唯一入参)时,总共有多少种投骰子的方法。

方法一:斐波那契数列
思路:设f(n)表示到第n步时总共有f(n)种投骰子的方法,那么到第n-1步时总共有f(n-1)种投骰子的方法;那么到第n-2步时总共有f(n-2)种投骰子的方法…
规律: 从第n-1步到第n步,只有一种可能性(投骰子结果为 1 ),所以从第n-1步到第n步共有f(n-1)*1 种投骰子的方法; 从第n-2步到第n步,只有一种可能性(投骰子结果为 2 ),所以从第n-2步到第n步共有f(n-2)*1 种投骰子的方法;
从第n-3步到第n步,只有一种可能性(投骰子结果为 3 ),所以从第n-3步到第n步共有f(n-3)*1 种投骰子的方法;
依次类推:f(n) = f(n-1)+f(n-2)+f(n-3)+…+f(1)+f(0),且f(1)=f(0)=1;
f(n-1)=f(n-2)+f(n-3)+…+f(1)+f(0)
所以f(n)=2f(n-1)
f ( n ) = 2 n − 1 f(n)=2^{n-1} f(n)=2n1

	n = int(input())
	print(2**(n-1))

方法二:动态规划-背包?

2. 拼凑钱币

给你六种面额 1、5、10、20、50、100
元的纸币,假设每种币值的数量都足够多,编写程序求组成N元(N为0~10000的非负整数)的不同组合的个数。

方法:动态规划

V = int(input())
f = [0]*(V+1)
f[0] = 1
n = 6
C = [1,5,10,20,50,100]
for i in range(n):
    for v in range(C[i],V+1):
        f[v] = sum((f[v],f[v-C[i]]))
print(f[V])

3. 最大矩形面积

给定一组非负整数组成的数组h,代表一组柱状图的高度,其中每个柱子的宽度都为1。 在这组柱状图中找到能组成的最大矩形的面积(如图所示)。
入参h为一个整型数组,代表每个柱子的高度,返回面积的值。

方法一
分治法:最大矩形面积只可能有三种情况:

  1. 取决于高度最小的柱子,此时面积等于高度乘总长度;
  2. 最大面积出现在高度最小的柱子左边;
  3. 最大面积出现在高度最小的柱子右边;
n = int(raw_input())
h = [int(x) for x in raw_input().split()]
 
def largestarea(a):
    l = len(a)
    idx = a.index(min(a))
 
    value1 = a[idx] * l
 
    if idx != 0:
        value2 = largestarea(a[0:idx])
    else:
        value2 = 0
    if idx != l-1:
        value3 = largestarea(a[idx+1:l])
    else:
        value3 = 0
        
    return max(value1, value2, value3)
 
print largestarea(h)

4. 最长公共连续子串

给出两个字符串(可能包含空格),找出其中最长的公共连续子串,输出其长度。

方法一
取较短字符串为move串,较长的是still串。move串从still串上面滑过,他们重叠部分是cover域,比较cover域对应字符。

a, b = raw_input(), raw_input()
if len(a) > len(b):  # 选择比较长的字符串作为still串
    s, m = a, b
else:
    s, m = b, a
len_s, len_m = len(s), len(m)  # still串和move串的长度。

max_len = 0
for i in range(len_m + len_s - 1):
    # 分三种情况确定cover域的范围
    if i < len_m - 1:  # move串没有完全进入still串
        s_range, m_range = (0, i + 1), (len_m - 1 - i, len_m)
    elif len_m-1 <= i <= len_s - 1:  # move串完全进入still串
        s_range, m_range = (i - len_m + 1, i + 1), (0, len_m)
    elif i > len_s - 1:  # move串开始脱出still串
        s_range, m_range = (i - len_m + 1, len_s), (0, len_s + len_m - 1 - i)

    s_cover, m_cover = range(*s_range), range(*m_range)  # still串和move串在cover域内的index

    l = 0
    for j in range(len(s_cover)):
        if s[s_cover[j]] == m[m_cover[j]]:
            l += 1
            if l > max_len:
                max_len = l
        else:
            l = 0
print max_len

方法二
经典动态规划问题,利用二维数组若是连续相等则必然存在 就可以利用状态转移关系 dp[i+1][j+1]=dp[i][j]+1 来累加最长连续长度

str1 = input()
str2 = input()
len1 = len(str1)
len2 = len(str2)
maxl = 0
dp = [[0 for _ in range(len2+1)] for _ in range(len1+1)]
for i in range(len1):
    for j in range(len2):
        if str1[i] == str2[j]:
            dp[i+1][j+1] = dp[i][j] + 1
        maxl = max(maxl, dp[i+1][j+1])
print(maxl)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值