20200802拼多多笔试题目

  • 第一题
    • python代码示例
  • 第二题
    • python代码
  • 第三题
    • 提交的版本
    • 完善版本
    • 双指针代码
  • 第四题

  拼爹爹的题目感觉出的还是比较有水准的,不管怎么样测试用例是比较多的。直接上题目。

第一题

大致题意就是玩飞行棋,给出初始位置K(距离终点的距离),然后给出丢了n次骰子。第二行输入n个数,代表骰子的值。
如果骰子的值没用完就到了终点,则需要输出paradox。
否则,最后输出两个数,分别代表飞行棋最终的位置,和回退的次数。(如果当前的骰子点数大于当前位置到终点的距离,
多出来的部分需要回退位置。)
输入:
10 2
6 3
输出示例 1 0
输入:
10 4
6 3 3 3
输出示例 1 2
输入:
6 3
4 2 6
输出示例 paradox

  这个题比较简单,主要是注意一下边界条件,因为边界条件测试的时候k可能就是0,这个时候也要输出"paradox",另一个边界条件就是最后一个骰子掷完之后可能到终点,这个时候不能输出"paradox"。

python代码示例

k ,n = [int(i) for i in input().split(' ')]N = [int(i) for i in input().split(' ')]
res = 0
for id,i in enumerate(N):if i==k and id!=n-1:print('paradox')exit(0)elif i<=k:k-=ielse:k=i-kres +=1print(k, res)

第二题

题目大致意思是,如果一个骰子可以通过上下,或者左右,或者前后翻转。如果通过若干次翻转后两个筛子的六个面点数
一样,则可以算作一个类骰子。
然后第一行输入一个整数n,表示有n个骰子。接下来的n行每行六个数,分别代表骰子的上下,左右,前后六个面的数字,然
后要求计算后输出,有多少类骰子,第二行输出每一类的骰子个数,需要降序排列。
示例 1:
输入:  2
1 2 3 4 5 6
1 2 6 5 3 4输出:
1
2
示例 2:
输入: 3 1 2 3 4 5 6 1 2 6 5 3 41 2 3 4 6 5
输出:
2
2 1
示例 3:
输入:
10
2 5 1 3 4 6
5 4 3 2 1 6
1 4 6 2 3 5
1 5 6 3 4 2
6 4 2 1 5 3
3 6 4 5 2 1
1 6 3 4 2 5
5 1 4 2 6 3
6 2 3 1 5 4
5 3 6 1 4 2输出:  9 2 1 1 1 1 1 1 1 1

  这个题算是蛮有趣的一个题目,因为很多人可能连怎么转都没搞清楚。但是这里就不细讲,可以分析一下,相对的面始终是相对的,可以把相对的面捆绑在一起。互换相对的面的时候,它们的侧面顺序是不变的。互换相对的面之后,上下会和左右颠倒,左右互换会和前后颠倒,前后互换会和左右颠倒。
  如果三组相对的面的组合一样的时候,一共会产生两种骰子,即正旋和反旋。接下来只需要判断是正旋还是反旋即可。
  把六个面中的三组中最小的数拿出来,记为x1,x2,x3,使得上,左,前(正方向)只从这三个数中产生。如果最后都把x1放在最上面,则有两种情况,x2放在最左面,x3放在最前面或者x2和x3反过来。只需要把这两种情况分清即可。
  所以先考虑把x1,x2,x3放到正方向,这个时候统计需要交换几次,这里的交换次数直接用比较统计了。然后考虑把x1放到最前面,比较一下需要交换几次,剩下的就是x2和x3的相对位置了,干脆把这个也记为一次序关系。
  最后总结出规律,如果这些情况下的交换次数为偶数,则是正旋的,交换次数为奇数,则是反旋的。然后统计两种情况分别有多少。
  用示例中的例子就是1,2,3,4,5,6显然是组内正序,不需要交换,组间也是正序。但是1,2,6,5,3,4,组内的逆序为1,组间的逆序为1,正好是一次旋转。
  好吧,我承认这种方式可能比较难以理解,但是是我考试的时候想出来的,如果大家有更好的理解,可以交流。

python代码


from collections import defaultdict
n = int(input())
res1 = defaultdict(lambda :0)
res2 = defaultdict(lambda :0)for i in range(n):cur = [int(i) for i in input().split(' ')]o = 0if cur[0] < cur[1]:o+=1if cur[2]<cur[3]:o +=1if cur[4]<cur[5]:o+=1a, b, c = tuple(sorted(cur[:2])), tuple(sorted(cur[2:4])), tuple(sorted(cur[4:]))if a[0]<b[0] :o+=1if a[0]<c[0]:o+=1if b[0]<c[0]:o+=1if o&1:res1[tuple(sorted([a,b,c]))]+=1else:res2[tuple(sorted([a,b,c]))]+=1print(len(res1)+len(res2))
for i in list(res1.values())+list(res2.values()), reverse=True):print(i, end=' ')

第三题

题目的大致意思是,一个人每天最多吃两顿饭,早餐和午餐,每餐只能选择一个套餐,每个套餐对应了一个热量值和美味值,这个人吃饭必须得满足两餐的总美味值高于预期,两顿饭都可以不吃。现在要求在满足美味值的条件下,热量值要最小。
输入三个数,m,n,t分别代表中餐套餐数目,晚餐套餐数目和美味值标准。要求输出最小摄入的热量值。如果怎么都达不到美味值,输出-1
示例 1:
输入: 
5 1 9
9 1
4 9
3 1
2 3
6 5
9 8
输出:4 (解释:只需要吃一顿中餐即可) 

示例 2:
输入:
1 1 0
3 1
2 1
输出: 0(解释,一顿都不吃)

示例 3:
输入:
3 3 10
1 1
2 5
3 7
2 4
4 8
6 9
输出: 5

示例 4:
输入:
2 1 4
3 1
2 1
1 2
输出:
-1(解释怎么都达不到美味值,输出-1) 

  思路就是把每个中餐拿出来去和晚餐配对,如果美味值大于预期,则看两者的能量和是否更小。因为晚餐已经是排好序了,我们可以倒序判断美味值是否大于预期。固定住中餐,一旦加上晚餐的美味值低于预期,内层循环立即跳出。
  这个题我只过了65,先贴代码。之后又优化外层循环提前退出和优化不对中餐进行排序,优化后代码还是65。

提交的版本

def main():n,m,t = [int(i) for i in input().split(' ')]if t ==0:print(0)returnres = float('inf')mid = [[0,0]]night = [[0,0]]for _ in range(n):mid.append([int(i) for i in input().split(' ')])mid.sort(key=lambda x:x[1])for _ in range(m):night.append([int(i) for i in input().split(' ')])night.sort(key=lambda x:x[1])print(mid)print(night)if mid[-1][1] + night[-1][1] < t: # 最大的营养值达不到预期print(-1)returnfor i in range(len(mid)-1, -1, -1):if mid[i][1] + night[-1][1] < t:breakfor j in range(len(night)-1, -1, -1):if mid[i][1] + night[j][1] >=t:res = min(res ,mid[i][0] + night[j][0])else:breakprint(res)if __name__ == '__main__':main()

  和过了这个题的人交流,把别人的思路也梳理一下,思想就是排序之后,如果有一个套餐能量比某些套餐能量大,但是美味值还低,这些套餐是一定都不会选的,干脆就把这些套餐剔除。这个思想的弊端在于删除这些套餐的是,需要重新建一个list,然后把不删除的放进list里。否则删除的复杂度也很大,会影响效果。改进后的代码如下。

完善版本

def deleteSupported(array):array.sort(key=lambda x:x[1],reverse=True)newArray = []pre = float('inf')for item in array:if item[0] < pre:pre = item[0]newArray.append(item)return newArray  # 注意,这里已经是倒序了,所以后面循环不需要倒序def main():n,m,t = [int(i) for i in input().split(' ')]if t ==0:print(0)returnres = float('inf')mid = [[0,0]]night = [[0,0]]for _ in range(n):mid.append([int(i) for i in input().split(' ')])mid = deleteSupported(mid)for _ in range(m):night.append([int(i) for i in input().split(' ')])night = deleteSupported(night)if mid[0][1] + night[0][1] < t:print(-1)returnfor i in range(len(mid)):if mid[i][1] + night[0][1] < t:breakfor j in range(len(night)):if mid[i][1] + night[j][1] >=t:res = min(res ,mid[i][0] + night[j][0])else:breakprint(res)if __name__ == '__main__':main()

  上面的代码已经可以通过(看别人的讨论说的)。既然到这一步,中餐和晚餐已经是排好序的序列了,而且也已经剔除了用不上的一部分套餐。这样还带来了一个好处,那就是如果选定了一个值,这样就不会存在既比当前选定的这个套餐营养值高,且能量低的套餐。所以这个时候,也不用遍历整个数组,直接选定中餐后,晚餐可以二分查找了,因为只需要一个营养值恰好满足目标值的套餐。就是这个中餐对应的最优解。
  但是二分查找就是最优的了吗?并不是,现在想想。既然中餐和晚餐都排好序了。中餐的营养值较小者必然对应晚餐营养值较大者,反之亦然。那么是否可以使用双指针,这个时候营养值越小,能量肯定也越小。中餐从小往大遍历,晚餐从大往小遍历,即可找到所有可能为最小值的组合。

双指针代码

def deleteSupported(array):array.sort(key=lambda x:x[1],reverse=True)newArray = []pre = float('inf')for item in array:if item[0] < pre:pre = item[0]newArray.append(item)return newArray  # 注意,这里已经是倒序了,所以后面循环不需要倒序def main():n,m,t = [int(i) for i in input().split(' ')]if t ==0:print(0)returnres = float('inf')mid = [[0,0]]night = [[0,0]]for _ in range(n):mid.append([int(i) for i in input().split(' ')])mid = deleteSupported(mid)for _ in range(m):night.append([int(i) for i in input().split(' ')])night = deleteSupported(night)if mid[0][1] + night[0][1] < t:print(-1)returni, j = len(mid)-1, 0while j<len(night) and i>=0:if mid[i][1] + night[j][1] >= t:res = min(res, mid[i][0] + night[j][0])j+=1else:i -=1print(res)

  关于这个题想写的就这么多了,值得一提的是,有人用上了输入数据小于10W这一条信息,直接用基于counting sort的思想,把这个题的复杂度按到了O(n)O(n)O(n)级别,但是掌握好通用思想就好了。

第四题

  是一道排列组合题,我自己没理顺,靠技巧过了一些case,后面搞懂了有空再贴。
  大致内容就是这样了,如果有瑕疵欢迎大家交流,也感谢大家指出我的错误。
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  
  

20200802拼多多笔试题目相关推荐

  1. Java算法:牛客网拼多多笔试真题算法Java版1-13题

    题号 题目 知识点 难度 通过率 PDD1 最大乘积 贪心模拟 中等 14.45%PDD2 大整数相乘 模拟 中等 27.32%PDD3 六一儿童节 贪心 中等 24.74%PDD4 迷宫寻路 模拟 ...

  2. 我胡汉三又回来了之拼多多笔试复盘

    天朗气清,惠风和畅.一个阳光明媚的日子,王豆子终于想起了被leetcode支配的恐惧以及TA的csdn账号,又回来了. 笔记本写不下了,所以用博客记录一下. 今天复盘一下拼多多的笔试,第一个题比较简单 ...

  3. 2021秋招拼多多笔试算法题

    1.现有一个n*m的矩阵,矩阵中每个格子都有且只有一种颜色.矩阵中共有k种颜色,每个颜色通过特定数字C(i,j)表示.设初始位置位于(1,1),每次可以向右(x+1,y)者向下(x,y+1)移动一个单 ...

  4. 拼多多笔试 公司套餐

    多多公司每天给员工提供免费的三餐,而小多由于习惯性赖床,所以他从来吃不 到早餐. 今天公司提供了N套中餐和M套晚餐,每种套餐分别有一个热量值X和美味值Y. 小多想知道,在满足美味值之和不少于T的情况下 ...

  5. 2021 8.8拼多多笔试第三题解答

    第三题输出括号匹配  输入包含 "( ) L R D " 题目以后补充.... import java.util.Arrays; import java.util.Scanner; ...

  6. 2019.4.3拼多多笔试第一题

    题目:给定一个元素个数为偶数的数组arr,将该数组中的元素两两配对并求和,在这些和中选出最大和最小值,请问该如何对其两两配对,才能让最大值和最小值的差为最小? 输入描述: 一共2行输入. 第一行为一个 ...

  7. 9-1拼多多笔试第四题

    题意:给出一个数n和m个数,求n关于m的子集. 思路:容斥原理,求所有m的集合,在这个集合的所有数,求一下lcm(最小公倍数),如果|集合|是奇数,ans+=n/lcm,否则ans-=n/lcm . ...

  8. 拼多多服务端研发工程师笔试

    拼多多服务端研发工程师笔试(2021年7月25日下午三点场) 前言+说明 一.算法编程题 题目描述 输入描述 输出描述 示例1 示例2 参考代码: 二.算法编程题 题目描述 输入描述 输出描述 示例1 ...

  9. 【编程练习】拼多多2021笔试真题集

    题目来源:牛客,拼多多2021笔试真题集 第一题:多多的数字组合 打卡题,很明显的两个约束:每个位数各不相同 + 数字最小,在这两个条件的约束下,N最大为45,对应的数字为123456789. 代码如 ...

最新文章

  1. GNN教程:DGL框架中的采样模型!
  2. Solaris基础系列之三:辅助工具
  3. 比较有意思的比较内表的小函数
  4. JavaScript的编程风格的见解
  5. 思科模拟器。计算机网络实验之四:RIPv2配置
  6. java 开发人员工具_Java开发人员应该知道的5种错误跟踪工具
  7. matlab 返回变量类型的命令,MATLAB主要命令汇总
  8. python (六)函数
  9. call_user_func和call_user_func_array的用法
  10. php读取大文件某行内容,PHP读取和修改大文件的某行内容_PHP教程
  11. rm: cannot remove ‘malloc.pro/.user.ini‘: Operation not permitted
  12. 在html中怎样使用%3c符号,5个JavaScript和9个JQuery经典面试题
  13. 在udp聊天器里如何给飞秋发消息
  14. VS2008 SP1 安装卡在 VS90sp1-KB945140-X86-CHS的解决方法
  15. 百度SEO站群全网音乐搜索下载网站源码
  16. openg-光照贴图
  17. 计算机查找的快捷键是,电脑快捷键快速查找
  18. 解决Android logcat: Unexpected EOF!方法指南
  19. wamp mysql 密码_WAMP中的mysql设置密码
  20. 参赛邀请 | 第二届古汉语自动分析国际评测EvaHan(古汉语机器翻译)开始报名...

热门文章

  1. 041 柯西中值定理证明及型三(ξ与a,b可分离)
  2. mysql的group语句_MySQL中distinct与group by语句的一些比较及用法讲解
  3. iOS app可视化开发(一)使用Xcode创建app
  4. “笨办法”学Python3,Zed A. Shaw, 习题7
  5. 服务器请求微信后台(api.weixin.qq.com)过慢处理
  6. prism 视图发现
  7. 五福背后的 Web 3D 引擎 Oasis Engine 正式开源
  8. 友华光猫设置虚拟服务器,中兴光猫sendcmd常用命令
  9. ukey的密码学原理
  10. virt-v2v 虚拟机到虚拟机的转换详解