拼多多学霸批后台第二批笔试

麻烦参加了拼多多这批笔试的大佬帮我分析一下下面的代码问题呀

第一次笔试紧张,第2,3题都没做出来,第4题都没时间看。

大家讨论一下呗。

"""
第2题
给定和S,要求得到一个长度为n的正整数递增序列 要求这个序列的和为S
输出满足以上要求的序列数目
eg. 输入 n, s = 2, 5 输出 2 因为满足条件的只有(1, 4), (2, 3)
算法:递推公式 dp[i][j][k] = sum(dp[i-1][1...j-1][x]) i表示序列长度 j表示给定和 k表示以k结尾的数 
解释: 因为要得到dp[i][j] 它是从长度为i-1的长度加上一个数k来的, 其中x<k
"""
def get_pre_sum(dp_i, j, k):
    res = 0
    for tmp_k in range(1, k):
        if j - k in dp_i.keys() and tmp_k in dp_i[j-k].keys():
            res += dp_i[j-k][tmp_k]
            res %= 1000000007
    return res
def suitable_sequence_count():
    """
    主程序
    """
    n, s = list(map(int, sys.stdin.readline().strip().split(' ')))
    dp = dict()   # 用字典hash存感觉比较方便
    tmp = dict()
    for i in range(s//n):
        tmp[i+1] = dict()
        tmp[i+1][i+1] = 1
    dp[1] = tmp   # 初始化 所有长度为1的和为s的都只有1个满足要求的序列
    # 按递推公式动态规划实现
    for i in range(1, n-1):
        for j in range(s):
            tmp = dict()
            k = 1
            while j - k + 1 > 0:
                tmp[j+1] = dict()
                tmp[j+1][k] = get_pre_sum(dp[i], j+1, k)
                k += 1
            if tmp:
                if i + 1 in dp:
                    dp[i+1][j+1] = tmp[j+1]
                else:
                    dp[i+1] = tmp
    res = 0
    if n <= 0 or s <= 0:  # 不合法输入
        res = 0
    elif n == 1:
        res = 1
    else:
        for k in range(1, s+1):
            res += get_pre_sum(dp[n-1], s, k)
    print(res)
"""  假设一个n长的项链,从0开始标记位置 该项链上共有p个珍珠(p<=n) 这些珍珠随机散落在项链上
求:把这个散落的珍珠汇聚在一起 即让他们连续摆放需要最少移动多少步
其中 0 和 n-1 位置视作相连续
eg. 输入 n=1000 p = 1, 4, 998, 995  输出 8  因为 1->0;4->1; 998->999;995->998共八步
算法: 要珍珠连续可以假设珍珠从i位置开始连续(i=[0, n)),要注意的情况是i <= n - p 这时候要从1开始循环 
    设置一个数组存放连续的位置[i...end], 始终把i看作是中间的位置n//2 因为是环所以相对位置不变的 这样也方便计算
    所以从i开始连续的最小移动步数 = min(i位置之前的第一颗珠子移到i, i位置之后的第一颗珠子移动到i(包括i))
"""
def pre_to_i_move(pre_i_purples, rear_i_purples, i, n):
    """
    用于计算i位置之前的第一颗珠子移到i所需步数
    :return:
    """
    move_times = 0
    for pos in pre_i_purples:
        move_times += (i - pos)
        i += 1  # 下一个位置需要移动 这里不取余是因为不可能pre_i_purles的数目超过一半
    for pos in rear_i_purples:
        move_times += abs(pos - i % n)  # 让i位置循环
        i += 1
    return move_times
def rear_to_i_move(pre_i_purples, rear_i_purples, i, n):
    """
    用于计算i位置之后的第一颗珠子移动到i(包括i)
    :return:
    """
    move_times = 0
    for pos in rear_i_purples:
        move_times += (pos - i)
        i += 1
    for pos in pre_i_purples[::-1]:
        move_times += (pos - i % n + n) % n
        i += 1
    return move_times
def purple_to_continue():
    """
    主程序
    """
    n = int(sys.stdin.readline().strip())
    purple_positions = list(map(int, sys.stdin.readline().strip().split(' ')))  # 初始输入的珍珠位置信息
    purple_positions.sort()   # 方便后面计算移动
    move_times = None
    pre_pos = None
    flag = True
    for pos in purple_positions:
        if pre_pos is not None and pos - pre_pos != 1:
            flag = False
            break
        pre_pos = pos
    if flag:  # 不用移动已经连续
        move_times = 0
    else:
        mid_pos = n // 2
        for i in range(n):
            redundance = mid_pos - i if i <= mid_pos else n - i + mid_pos  # 为了把i位置看作是中间的位置方便计算
            pre_i_purples = []
            rear_i_purples = []
            for pos in purple_positions:  # 因为purple_positions是有序的遍历到某个位置的相对位置是不变的
                tmp_pos = (pos + redundance) % n
                if tmp_pos < mid_pos:
                    if pre_i_purples and pre_i_purples[0] > tmp_pos:
                        pre_i_purples.insert(0, tmp_pos)
                    else:
                        pre_i_purples.append(tmp_pos)
                else:
                    if rear_i_purples and rear_i_purples[0] > tmp_pos:
                        rear_i_purples.insert(0, tmp_pos)
                    else:
                        rear_i_purples.append(tmp_pos)
            tmp = min(pre_to_i_move(pre_i_purples, rear_i_purples, mid_pos, n),
                      rear_to_i_move(pre_i_purples, rear_i_purples, mid_pos, n))
            if move_times is None or move_times > tmp:
                move_times = tmp
    print(move_times)
#拼多多##笔试题目##秋招#
全部评论
请问楼主有更加详细的解读嘛 有点看不懂呀~~~~
点赞 回复 分享
发布于 2019-08-19 10:41
e
点赞 回复 分享
发布于 2019-08-19 10:41
你珍珠这题做出来了?
点赞 回复 分享
发布于 2019-08-12 18:26

相关推荐

01-14 16:23
广州商学院 Java
双非后端失败第N人:如果准备好了可以直接投字节,字节是最不看学历的,只要想面,大概率都能给你约面。
双非有机会进大厂吗
点赞 评论 收藏
分享
评论
1
14
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务