PDD 拼多多笔试 ac,ac,ac,40%

第一题
把数组a 从大到小排列,三个三个的计算。
from sys import stdin

N = int(stdin.readline())
A = list(map(int, stdin.readline().split()))
A.sort(reverse=True)

sum_value = 0
for i in range(int(len(A) / 3)):
    sum_value += A[i * 3]
    sum_value += A[i * 3 + 1]

index = int(len(A) / 3) * 3

sum_value += sum(A[index:])

print(sum_value)


第二题
开一个数组,长度为M
from sys import stdin

N, M = map(int, stdin.readline().split())
A = list(map(int, stdin.readline().split()))

mod_dic = {0: 1}
for i in range(M):
    mod_dic[i + 1] = 0


sum = 0
num = 0

for item in A:
    sum += item
    sum %= M
    num += mod_dic[sum]
    mod_dic[sum] += 1

print(num)


第三题
找到对于每个数字0-9, 使得数组中至少有k 个这样的数字,需要的代价。
排序找到代价最小的那个。
容易发现,要取得字典序最小的那个,要从后往前replace比k 小的值为k, 从前往后replace 比k 大的值为k。
from sys import stdin
import copy


def cal_cost(number, index, K, string):
    if number[index] >= K:
        return 0, string

    else:
        cost = 0
        K -= number[index]
        for i in range(1, 10):
            if index + i < 10:
                num = min(K, number[index + i])
                string = string.replace(str(index + i), str(index), num)
                cost += (num * i)
                K -= num
            if index - i >= 0:
                num = min(K, number[index - i])
                string = string[::-1].replace(str(index - i), str(index), num)
                string = string[::-1]
                cost += (num * i)
                K -= num
            if K == 0:
                break
        return cost, string


def return_first_item(item):
    return item[0]


N, K = map(int, stdin.readline().split())

original_string = stdin.readline()[:-1]

number = [0 for i in range(10)]

for item in original_string:
    number[ord(item) - ord('0')] += 1

list = []

for i in range(10):
    cost, best_choice = cal_cost(number, i, K, copy.copy(original_string))
    list.append((cost, best_choice))

list.sort(key=return_first_item)

min_value, string = list[0]

for item in list:
    if item[0] > min_value:
        break
    string = min(string, item[1])

print(min_value)
print(string)
第四题
dp, 我的算法复杂度为O(N^2)
只过了40%
from sys import stdin

N, K = map(int, stdin.readline().split())
C = list(map(int, stdin.readline().split()))

dp = [[0 for i in range(N + 1)] for j in range(K + 1)]

dp[0][0] = 0
dp[0][1] = 1
for i in range(1, N + 1):
    if C[i - 1] == C[i - 2]:
        dp[0][i] = dp[0][i - 1] + 1
        if dp[0][i] >= N - K:
            print(N - K)
            exit()

    else:
        dp[0][i] = 1

for i in range(1, K + 1):
    dp[i][0] = 0
    dp[i][1] = 1
    for j in range(2, N + 1):
        dp[i][j] = 1
        for k in range(min(i + 1, j)):
            if C[j - 1] == C[j - k - 2]:
                dp[i][j] = max(dp[i][j], dp[i - k][j - k - 1] + 1)

print(max(dp[K]))



#拼多多春招笔试##笔试题目##拼多多#
全部评论
第二题 不是很能理解为什么直接:mod_dic = {0: 1}
点赞 回复 分享
发布于 2020-04-10 21:57
dp = [[0 for i in range(N + 1)] for j in range(K + 1)] 这句当数据规模比较大的时候会很慢
点赞 回复 分享
发布于 2020-04-10 22:55
大佬很强,我只AC第一题😂😂
点赞 回复 分享
发布于 2020-04-10 22:58
大佬你是什么岗 感觉和你题不一样呢
点赞 回复 分享
发布于 2020-04-10 23:03
第二题能详细说说思路嘛
点赞 回复 分享
发布于 2020-04-10 23:06
第三题找到记录一个数组,第一位为绝对值,第二位为指针位置。然后排序key = lambda x:(x[0], -x[-1])找出绝对值最小,且指针靠后的那k个值,这个时候再把这k个值记录指针的位置替换为需要的值。我当时傻了,排序没加那个负号。一个小时都没反应过来。第四题,直接维护一个窗口,用hashmap记录指针间的值,这题就类似leetcode424,原题目是删方块,现在是改方块,道理一样,之前比较r-l+1,现在比较,更新前最大maxfreq,res, 和window[num]。时间复杂度O(n)
点赞 回复 分享
发布于 2020-04-10 23:12
我第四题也是用动态规划,然后也是40%,后来换用粗暴方法,变成70%。因为我感觉这里面是没办法用动态规划的。 因为这里有个问题,就是dp[i]更新的时候,比如找到前一个相同颜色的色块,此时这个色块dp[j]代表的连续色块,肯定是包含了他更前面的色块的,这样的话就有问题了,因为有可能我只需要包含这个色块,而不需要包含再前面的色块,然后dp[j]却包含了,就是说,结果就从动态规划变成了贪心,自然就出错。 不过我也不知道具体应该怎么做,题主有什么想法没有
点赞 回复 分享
发布于 2020-04-11 00:20
第四题 离散化+滑动窗口,不知道写的对不对,有巨佬看看有问题没 public static void main(String[] args) {         Scanner sc = new Scanner(System.in);         int N = sc.nextInt();         int K = sc.nextInt();         int cnt = 0;         int[] C = new int[N];         Map<Integer, Integer> map = new HashMap<>();         for (int i = 0; i < N; i++) {             int t = sc.nextInt();             if (!map.containsKey(t)){                 map.put(t, cnt++);             }             C[i] = map.get(t);         }         int[] count = new int[cnt];         int left=0, right=0, result=0, maxCount=0;         while (right<C.length){             count[C[right]]++;             maxCount = Math.max(maxCount, count[C[right]]);             if (right-left+1-maxCount>K){                 count[C[left]]--;                 left++;             }             right++;         }         System.out.println(maxCount); }
点赞 回复 分享
发布于 2020-04-11 05:06
第二题能详细说明一下吗?麻烦你了
点赞 回复 分享
发布于 2020-04-11 05:56
https://pasteme.cn/32979 三四题ac代码 3是贪心,4是尺取
点赞 回复 分享
发布于 2020-04-11 10:07
大佬,我的思路和你是一样的,为什么我的通过率只有 10%,50%,15%,0%呢??🤣
点赞 回复 分享
发布于 2020-04-11 21:00

相关推荐

一颗宏心:华为HR晚上过了十二点后还给我法消息。
点赞 评论 收藏
分享
评论
10
30
分享
牛客网
牛客企业服务