拼多多2019实习算法岗招聘笔试记录

时间:2024-11-18 07:45:04

在经过了腾讯的洗礼后,这次拼多多的笔试做的还不错。2个小时4道编程题,都做对了。在此凭记忆写下题目并给出解答。

第一题:给一组数,数的个数是偶数,两两配对求和,使得和的最大值减去和的最小值最小。求这个差值。

题目看上去挺难的,当时想了一下感觉就是排序后第一个和最后一个组合,第二个和倒数第二个组合……记录一下最大值和最小值就行了。后来提交上去AC了。改天用数学证明一下这种配对方式是使得最小差值的。

  1. #include <iostream>
  2. #include <vector>
  3. #include <algorithm>
  4. using namespace std;
  5. int main()
  6. {
  7. int n;
  8. cin>>n;
  9. vector<int> nums(n);
  10. for (int i=0;i<n;i++)
  11. {
  12. cin>>nums[i];
  13. }
  14. sort((),nums.end());
  15. int max_record=0,min_record=300;
  16. for (int i=0;i<n/2;i++)
  17. {
  18. max_record=max(max_record,nums[i]+nums[n-i-1]);
  19. min_record=min(min_record,nums[i]+nums[n-i-1]);
  20. }
  21. cout << max_record-min_record;
  22. return 0;
  23. }

 

第二题:给定0到9十个数字的每个数字的可使用次数,以及A和B两个数的位数,让A和B选择可使用的数字进行组合,使得A*B最小,求这个最小值。

比如 给定0到9的数字各一个: 1 1 1 1 1 1 1 1 1 1 A和B的位数都是2。那么A=01,B=23,可以使得结果最小(A和B都可以有前导0)。

首先有一个点可以肯定的是,A或B拿到数字后,数字肯定是按从小到大的顺序排列的。所以我第一想法是A和B依次拿走剩下数字中最小的那一个。事实上这样不行,上面的例子就是一个反例,按照这种拿法,A=03,B=12,乘积是36,比01*23=23要大。这种方法得了25分。后来又想着说是不是A先拿最小的,A拿完了B再拿,交上去后也不对,只有15分。

把3 4题都做完后再回来做这道题,发现既然A和B都只拿最小的数字,那么其实有很多冗余的给出的数字,这些数字是没有用的。先把这些数字去掉,再进行组合,然后穷举就可以算出A*B的最小值了。这里要用到求组合的算法。

  1. #include <iostream>
  2. #include <vector>
  3. using namespace std;
  4. //012,…… ,n-1这n个数字中取k个数字的所有组合方式,结果储存在res中
  5. void DFS(int n,int k,vector<vector<int>> &res,vector<int>& combination,int step)
  6. {
  7. if(combination.size()>k)
  8. {
  9. return;
  10. }
  11. if(step==k-1)
  12. {
  13. res.push_back(combination);
  14. return;
  15. }
  16. int start;
  17. if(())
  18. start=-1;
  19. else start=();
  20. for(int i=start+1;i<n;i++)
  21. {
  22. combination.push_back(i);
  23. DFS(n,k,res,combination,step+1);
  24. combination.pop_back();
  25. }
  26. }
  27. int main()
  28. {
  29. vector<int> counts(10);
  30. for(int i=0;i<10;i++)
  31. {
  32. cin>>counts[i];
  33. }
  34. int A_len,B_len;
  35. cin>>A_len;
  36. cin>>B_len;
  37. if(counts[0]>=min(A_len,B_len))
  38. {
  39. cout<<0;
  40. return 0;
  41. }
  42. vector<int> record;
  43. for(int i=0;i<A_len+B_len;i++)
  44. {
  45. for(int j=0;j<counts.size();j++)
  46. if(counts[j]!=0)
  47. {
  48. counts[j]--;
  49. record.push_back(j);
  50. break;
  51. }
  52. }
  53. vector<vector<int>> index;
  54. vector<int> combination;
  55. DFS(A_len+B_len,A_len,index,combination,-1);
  56. long long res,A,B;
  57. for(int i=0;i<index.size();i++)
  58. {
  59. vector<bool> choose_A(A_len+B_len,false);
  60. for(int j=0;j<index[i].size();j++)
  61. {
  62. choose_A[index[i][j]]=true;
  63. }
  64. A=0;
  65. B=0;
  66. for(int j=0;j<A_len+B_len;j++)
  67. {
  68. if(choose_A[j])
  69. A=10*A+record[j];
  70. else
  71. B=10*B+record[j];
  72. }
  73. if(i==0) res=A*B;
  74. else res=min(A*B,res);
  75. }
  76. cout<<res;
  77. return 0;
  78. }

 

第三题:给定一个数组,和一个数字d,求数组中两个数之差大于等于d的概率。数组长度1<=L<=100,数字大小1<=s[i]<=50,1<=d<=50。结果保留6位小数。

例如输入:

{1,2,3}

2

输出:0.333333

这个题当时看到就觉得很简单,估计是想考我们会不会输出小数以及解析输入(输入是包括大括号{ }和逗号,的)。我是先用字符串读输入,再转化成数组。

  1. #include <iostream>
  2. #include <vector>
  3. #include <string>
  4. using namespace std;
  5. int main()
  6. {
  7. vector<int> S;
  8. string input;
  9. cin>>input;
  10. int len=input.length();
  11. if(len==4)
  12. S.push_back((input[1]-'0')*10+input[2]-'0');
  13. else
  14. S.push_back(input[1]-'0');
  15. while(true)
  16. {
  17. cin>>input;
  18. len=input.length();
  19. if(len==3)
  20. S.push_back((input[0]-'0')*10+input[1]-'0');
  21. else
  22. S.push_back(input[0]-'0');
  23. if(input.back()=='}')
  24. break;
  25. }
  26. int d;
  27. cin>>d;
  28. int right=0,sum=S.size()*(S.size()-1)/2;
  29. for(int i=0;i<S.size();i++)
  30. {
  31. for(int j=i+1;j<S.size();j++)
  32. {
  33. if(abs(S[i]-S[j])<=d)
  34. {
  35. right++;
  36. }
  37. }
  38. }
  39. printf("%0.6f",double(right)/sum);
  40. return 0;
  41. }

 

第四题:求一个单词word1到word2的最少操作次数。操作包括增加、删除和修改。

这道题在上次腾讯面试中遇见过,当时没有做出来(并且面试前我还在leetcode中看到过这道题)我的博客:腾讯面试经历

这一次很快的就做出来了,基本思路就是动态规划,其实很简单。

  1. #include <iostream>
  2. #include <string>
  3. #include <vector>
  4. using namespace std;
  5. int main()
  6. {
  7. string w1,w2;
  8. cin>>w1;
  9. cin>>w2;
  10. int len1=w1.length(),len2=w2.length();
  11. vector<vector<int>> dp(len1+1,vector<int>(len2+1,0));
  12. dp[0][0]=0;
  13. int tmp;
  14. for(int i=0;i<=len1;i++)
  15. {
  16. for(int j=0;j<=len2;j++)
  17. {
  18. tmp=5000;
  19. if(i==0&&j==0) continue;
  20. if(i>0)
  21. {
  22. tmp=dp[i-1][j]+1;
  23. }
  24. if(j>0)
  25. {
  26. tmp=min(tmp,dp[i][j-1]+1);
  27. }
  28. if(i>0&&j>0)
  29. {
  30. if(w1[i-1]==w2[j-1])
  31. tmp=min(tmp,dp[i-1][j-1]);
  32. else
  33. tmp=min(tmp,dp[i-1][j-1]+1);
  34. }
  35. dp[i][j]=tmp;
  36. }
  37. }
  38. cout<<dp[len1][len2];
  39. }

 

接下来应该有面试机会,加油吧!