2019腾讯春招暑期实习提前批编程题

墨蓝 2022-03-07 08:42 424阅读 0赞

错过了腾讯的春招编程题(在牛客笔试前已经电话面所以就没参加,有自己做C++的笔试,对C++不熟,感觉已经凉了),但是朋友做了便截图下来然后自己练习一下,给我的感觉就是,会做的就很快写完,不会的基本没有什么思路,总之很快写完了三道题,但是有两道是不会的。下面按题目给出我的代码,有错的恳请指正。

1、

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjM2Mzk5Nw_size_16_color_FFFFFF_t_70

不要看到这个就以为是背包问题,这个是从大到小的,也就是说什么面值的货币都有,所以就不存在比如货币是{1,6,7},而输入30的情况下,如果按下面的算法就出错了,按下面的算法,此时应该得到4*7+2*1=30,要6个货币,但假如是6*5=30只要5个货币。但题目给的是n种货币,所以假如先4*7+1*2=30,也是只要5个货币,所以本题很简单。。。

  1. public static void lessCoins(){
  2. String [] lines = scanner.nextLine().split(" ");
  3. int n = Integer.parseInt(lines[0]),m = Integer.parseInt(lines[1]);
  4. int count = 0,temp = 0;
  5. while (m>0){
  6. temp = n;
  7. while (temp>m){
  8. temp--;
  9. }
  10. m-=temp;
  11. count++;
  12. }
  13. System.out.println(count);
  14. }

如果按照前面说的,那要简单动态规划了,动态规划基本就是两个步骤,定义状态,然后递推转移方程,如果想要详细了解动态规划,那么可以参考别的文章。

  1. public static int getLessCoinsCount(int []coins,int amount){
  2. int []dp = new int[amount+1];
  3. for(int i=1;i<=amount;i++){
  4. int min = Integer.MAX_VALUE;
  5. for(int j=0;j<coins.length;j++)
  6. if(coins[j]<=i)min = Math.min(min,dp[i - coins[j]]+1);
  7. dp[i] = min == Integer.MAX_VALUE?0:min;
  8. }
  9. return dp[amount]>amount?-1:dp[amount];
  10. }

2、

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjM2Mzk5Nw_size_16_color_FFFFFF_t_70 1

这个watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjM2Mzk5Nw_size_16_color_FFFFFF_t_70 2其实就是累加的意思,只是要对加数做个求余判断。

  1. public static int getSum(int start,int end){
  2. int sum = 0;
  3. for (int i = start;i<=end;i++){
  4. if(i%2==0) sum += i;
  5. else sum -= i;
  6. }
  7. return sum;
  8. }
  9. int n = Integer.parseInt(scanner.nextLine());
  10. int [][]res = new int[n][2];
  11. int []r = new int[n];
  12. String [] strs = null;
  13. for (int i = 0;i<n;i++){
  14. strs = scanner.nextLine().split(" ");
  15. res[i][0] = Integer.parseInt(strs[0]);
  16. res[i][1] = Integer.parseInt(strs[1]);
  17. }
  18. for (int i = 0;i<n;i++){
  19. r[i] = getSum(res[i][0],res[i][1]);
  20. System.out.println(r[i]);
  21. }

3、

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjM2Mzk5Nw_size_16_color_FFFFFF_t_70 3watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjM2Mzk5Nw_size_16_color_FFFFFF_t_70 4

这题可能同学想到的,就是先枚举所有排列,再和原来的数组做比较,得到结果相等时计数加1,当超过1e9+7时对计数取1e9+7的余数,相信大部分人都这么想,但是,这肯定是不可取的,17的阶乘都超过了int的最大范围,何况这里有最多2000个数,那肯定是不可计算的。想一下,假设在相等的情况,有s个1,其他均为0,那么就有Cn的s种,而其他的还有2的(n-s)次方,因为0、1、2,只能有2种可能是能赢的,而这些数也是有n-s个数,于是得到公式gif.latex_C_7Bn_7D_5E_7Bs_7D_5Ccdot2_5E_7B_28n-s_29_7D。所以代码就很简单了:

  1. public static int calC(int n,int s){
  2. int count = 1, e = n - s;
  3. for (int i = s + 1;i<=n;i++){
  4. count *=i;
  5. if(count>1000000007)count%=1000000007;
  6. }
  7. while (e>0){
  8. count *= 2;
  9. if(count>1000000007)count%=1000000007;
  10. e --;
  11. }
  12. return count;
  13. }

因为我没有提交过题目,也不知道对不对,但是举几个例子都是没有问题的,在s,n的范围内也是算得很快,如果不对的请指正。

4、

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjM2Mzk5Nw_size_16_color_FFFFFF_t_70 5watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjM2Mzk5Nw_size_16_color_FFFFFF_t_70 6

看到这题,是不是感觉跟计算最长子串的思想有点那么相似,如果你要这么想,就往复杂里面想了。相信学过计算机网络的同学应该都听说过滑动窗口,滑动窗口应该就是在传送报文时可以动态更新的长度,窗口长度受对方主机反馈的影响。我觉得这个意思很像啊,说下我的思路,因为要求所有颜色要命中,于是用一个list去装这个序列,这个序列肯定都包含所有颜色但也可能有重复的颜色,因为这个滑动窗口就是记录原来数组中连续最少的枪数,此外我们还要判断什么这个list满足包含所有颜色,当包含所有颜色时,就得到一个序列,这个满足条件的序列长度就被保存下来到一个res_list中,到最后对res_list排序,取最前面的数就是最小的长度。那么关键问题就是,滑动窗口怎么设计,其实很简单,因为滑动窗口要满足包含所有颜色,暂且用一个队列来保存这个滑动窗口,只有当要入队元素和队首元素一样时,我们才对队列操作,即队首元素出队,然后再入队,这就能保证当前队列不会有多余的步长,当然,你非要说中间有相同的数,那我只能说没有影响。当得到一个可用序列后,滑动窗口要更新的,就是删除队首,当队首元素后有队首元素时,删除队首元素直到没有。于是代码就出来了:

  1. public static int lessShotCounts(int a[],int m){
  2. ArrayList<Integer> res_list = new ArrayList<>();//所有满足条件的窗口长度
  3. ArrayList<Integer> list = new ArrayList<>();//得到一条路线的标志
  4. LinkedList<Integer> t_list = new LinkedList<>();//滑动窗口的数组
  5. for(int i = 0;i<a.length;i++){
  6. if(!list.contains(a[i])){
  7. list.add(a[i]);
  8. t_list.add(a[i]);
  9. }
  10. else{
  11. if(t_list.get(0) == a[i]){
  12. t_list.remove((Object)a[i]);
  13. }
  14. t_list.add(a[i]);
  15. }
  16. boolean flag = false;
  17. if(list.contains(0) && list.size() == m + 1) flag = true;
  18. if(!list.contains(0) && list.size() == m ) flag = true;
  19. if(flag){
  20. System.out.println(Arrays.toString(t_list.toArray()));
  21. res_list.add(t_list.size());
  22. if(t_list.get(0)!=null){
  23. int temp = t_list.get(0);
  24. t_list.remove((Object)temp);
  25. list.remove((Object)temp);
  26. if(t_list.get(0)!=null){
  27. temp = t_list.get(0);
  28. while (t_list.lastIndexOf(temp) !=0 && t_list.get(0)!=null){
  29. t_list.remove((Object)temp);
  30. temp = t_list.get(0);
  31. }
  32. }
  33. }
  34. }
  35. }
  36. if(res_list.size()==0)return -1;
  37. else{
  38. Collections.sort(res_list);
  39. return res_list.get(0);
  40. }
  41. }

结果:

20190316175942335.png

5、

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjM2Mzk5Nw_size_16_color_FFFFFF_t_70 7

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MjM2Mzk5Nw_size_16_color_FFFFFF_t_70 8

这个题目我暂时还没有头绪,等我想到了再分享,或者有会的同学可以分享给我,十分感谢。

发表评论

表情:
评论列表 (有 0 条评论,424人围观)

还没有评论,来说两句吧...

相关阅读

    相关 2017暑期实习编程2

    题目描述: 小Q最近遇到了一个难题:把一个字符串的大写字母放到字符串的后面,各个字符的相对位置不变,且不能申请额外的空间。 你能帮帮小Q吗? 输入描述 : 输入

    相关 2019年秋提前面筋

    综述 本人非科班生,本科普通二本院校、硕士西安某末流985,本硕专业都是电子与通信工程,基本做的东西离不开单片机、DSP、FPGA、STM32,先前完全没有接触过网络、数

    相关 2019暑期实习提前编程

    错过了腾讯的春招编程题(在牛客笔试前已经电话面所以就没参加,有自己做C++的笔试,对C++不熟,感觉已经凉了),但是朋友做了便截图下来然后自己练习一下,给我的感觉就是,会做的就