拼多多2021笔试真题集 (牛客网)

这篇博客介绍了四个编程问题的解决方案:寻找特定和的数字组合,计算字符串变为相同字符串的最小代价,找出和谐区间的数量,以及对骰子进行分类。每个问题都提供了相应的Java代码实现,并分析了解题思路,涉及贪心算法、字符串处理和数组操作。
摘要由CSDN通过智能技术生成

题目1:

多多君最近在研究某种数字组合:
定义为:每个数字的十进制表示中(0~9),每个数位各不相同且各个数位之和等于N。
满足条件的数字可能很多,找到其中的最小值即可。
多多君还有很多研究课题,于是多多君找到了你--未来的计算机科学家寻求帮助。

代码:

思路分析:

1、首先最大的数字组合为987654321,和为45,所以大于45的数不存在数字组合。

2、接着如果这个数<10的话,说明最小值肯定是一位数的时候最小,即是它本身。

3、其他情况,因为想要求最小值,所以肯定是希望个位数上的数字尽可能大,高位上的数字尽可能小,才能构成最小值(感觉有点贪心的思想)。

import java.util.*;

public class Main{
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        if(n > 45){
            System.out.println(-1);
            return;
        }
        if(n < 10){
            System.out.println(n);
            return;
        }
        int num = 0;
        int digit = 0;
        for(int i = 9;i > 0;i--){
            if(n != 0 && i <= n){
                n -= i;
                num += (int)Math.pow(10, digit)*i;
                digit++;
            }
        }
        System.out.println(num);
    }
}

题目2: 

多多君最近在研究字符串之间的变换,可以对字符串进行若干次变换操作:

  1. 交换任意两个相邻的字符,代价为0。
  2. 将任意一个字符a修改成字符b,代价为 |a - b|(绝对值)。

现在有两个长度相同的字符串X和Y,多多君想知道,如果要将X和Y变成两个一样的字符串,需要的最少的代价之和是多少。

 代码:

思路分析:

1、因为交换字符不需要代价,所以选择先将两个字符数组排序

2、然后定义双指针分别指向两个字符数组开始的位置,如果相等则两个指针前进1,否则,需要付出更改元素的代价abs(str1[pre1] - str2[pre2])

import java.util.*;

public class Main{
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        int n = Integer.parseInt(scan.nextLine());
        String s1 = scan.nextLine();
        String s2 = scan.nextLine();
        char[] str1 = s1.toCharArray();
        char[] str2 = s2.toCharArray();
        Arrays.sort(str1);
        Arrays.sort(str2);
        int pre1 = 0;
        int pre2 = 0;
        int cost = 0;
        for(int i = 0;i < n;i++){
            if(str1[i] == str2[i]){
                pre1++;
                pre2++;
            }else{
                cost += Math.abs(str1[i] - str2[i]);
            }
        }
        System.out.println(cost);
    }
}

 题目3:

多多路上从左到右有N棵树(编号1~N),其中第i个颗树有和谐值Ai。

多多鸡认为,如果一段连续的树,它们的和谐值之和可以被M整除,那么这个区间整体看起来就是和谐的。
现在多多鸡想请你帮忙计算一下,满足和谐条件的区间的数量。

  代码:

思路分析:

1、数学推理,假设pre[i]代表前i个元素的和,所以[j,i]要满足和谐区间的条件,需要

pre[i] - pre[j-1] = M*(0,1,2,...)

也就是说pre[i] % M取余的值 等于 pre[j-1] % M的值,说明[j,i]区间的和sum是M的倍数。

2、明白以上原理就很好做了,定义一个map来存储前缀和pre出现的次数。但这里要注意的是因为有测试用例数很大,所以不能用int类型,要用Long来定义才能通过测试用例。

import java.util.*;

public class Main{
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        int n = scan.nextInt();
        int m = scan.nextInt();
        int[] nums = new int[n];
        for(int i = 0;i < n;i++){
            nums[i] = scan.nextInt();
        }
        Map<Long,Long> map = new HashMap<>();
        map.put(0L,1L);
        long pre = 0;
        long count = 0;
        for(int i = 0;i < n;i++){
            pre += nums[i];
            long mod = pre % m;
            if(map.containsKey(mod)){
                count += map.get(mod);
            }
            map.put(mod,map.getOrDefault(mod,0L)+1);
        }
        System.out.println(count);
    }
}

  题目4:

多多君拼团购买了N个骰子,为了方便后面进行活动,多多君需要将这些骰子进行分类。

两个骰子为同类的定义是:

1

将其中一个骰子通过若干次上下、左右或前后翻转后,其与另一个骰子对应的6面数字均相等。

现在多多君想知道不同种类的骰子的数量分别有多少

  代码:

 思路分析:

找到骰子的规律,就固定1为骰子的上表面,然后看1的四侧对应的值,当1所在位置不同,对应的值不同,可能得出的数不同,所以需要调换顺序之后,存储入map中,key是四个侧面对应的值val,value值是同类型骰子的数量。这题主要还是找规律很难。

import java.util.*;

public class Main{
    public static void main(String[] args){
        Scanner scan = new Scanner(System.in);
        int N = scan.nextInt();
        Map<Integer,Integer> map = new HashMap<>();
        for(int n = 1;n <= N;n++){
            int[] a = new int[6];
            for(int i = 0;i < 6;i++){
                a[i] = scan.nextInt();
            }
            int val = 0;
            for(int i = 0;i < 6;i++){
                if(a[i] == 1){
                    if(i % 2 == 0){
                        val = a[(i+2)%6]*1000 + a[(i+4)%6]*100 + a[(i+3)%6]*10 + a[(i+5)%6];
                    }else{
                        val = a[(i+4)%6]*1000 + a[(i+2)%6]*100 + a[(i+3)%6]*10 + a[(i+1)%6];
                    }
                    break;
                }
            }
            for(int i = 0,tmp = val;i < 3;i++){
                tmp = tmp/10 + (tmp%10*1000);
                val = Math.min(val,tmp);
            }
            map.put(val,map.getOrDefault(val,0)+1);
        }
        List<Integer> ans = new ArrayList<>();
        for(int key : map.keySet()){
            ans.add(map.get(key));
        }
        Collections.sort(ans);
        System.out.println(ans.size());
        for(int i = ans.size() - 1;i > 0;i--){
            System.out.print(ans.get(i) + " ");
        }
        System.out.println(ans.get(0));
    }
}

  • 6
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值