9.1 拼多多寻梦计划笔试题复盘

刷题少,考得不好,痛定思痛,参考了评论区很多大佬的解答贴,复盘整理出来。

第1道

读入一个数列和N值,返回按优先级排序的N个数,满足

(1)所有偶数优先级大于奇数

(2)同为偶数或同为奇数时,数值大的优先级高

输入描述:

每个测试输入的测试用例,包含一个用半角逗号(,)分开的自然数数列和1个参数N,数列和参数N用半角分号(;)隔开这里保证N小于数列的元素个数(不超过100)。

输出描述:

在一行内输出N个满足题目条件的自然数,用逗号隔开

示例1

输入:

555503,772867,756893,339138,399447,40662,859037,628085,855723,974471,599631,636153,581541,174761,948135,411485,554033,858627,402833,546467,574367,360461,566480,755523,222921,164287,420256,40043,977167,543295,944841,917125,331763,188173,353275,175757,950417,284578,617621,546561,913416,258741,260569,630583,252845;10

输出:

913416,566480,420256,339138,284578,40662,977167,974471,950417,948135


import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Scanner;

public class Main {
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        String line = sc.next();
        String[] split = line.split(";");
        int N = Integer.valueOf(split[1]);
        String[] nums = split[0].split(",");
        List<Long> nums_1 = new ArrayList<>();
        List<Long> nums_2 = new ArrayList<>();
        for (int i = 0; i < nums.length; i++) {
            long t = Long.valueOf(nums[i]);
            if (t % 2 == 0) {
                nums_2.add(t);
            } else {
                nums_1.add(t);
            }
        }
        Collections.sort(nums_1, Collections.reverseOrder());
        Collections.sort(nums_2, Collections.reverseOrder());
        List<Long> res = new ArrayList<>(N);
        for (int i = 0; i < Math.min(nums_2.size(), N); i++) {
            res.add(nums_2.get(i));
        }
        if (res.size() < N) {
            for (int i = res.size(), j = 0; i < N; i++, j++) {
                res.add(nums_1.get(j));
            }
        }
        for (int i = 0; i < N; i++) {
            if (i == 0)
                System.out.print(res.get(i));
            else
                System.out.print("," + res.get(i));
        }
    }
}

第2道


产品经理小梅喜欢和他的男朋友小白一块玩扑克游戏。每一局,小梅抽取N张扑克牌,自左向右依次排列在桌面上;小白也抽取M(8>=N>=M>=1)张扑克牌,自左向右依次排列在桌面上。
小梅需要进行N个回合,使用手中的扑克牌,组成一个新的扑克牌的序列每个回合,小梅有d、l、r三种策略
选择d时,小梅将最左边的扑克牌丢弃
选择l时,小梅将最左边的扑克牌取出,放到新的扑克牌序列的最左边
选择r时,小梅将最左边的扑克牌取出,放到的扑克牌序列的最右边
N个回合完成,新的扑克牌序列与小白的扑克牌完全样(只考虑数字,不考虑花色),则小梅胜出
小梅向程序员小岛提了一个需求,希望了解获胜的全部方法。简化起见扑克牌仅包合1-9。

输入描述:

首先,输入数字S,作为局数(1<=10)每一局,分别输入两行字符串,分别代表小梅的抽取的扑克牌(从左向右排列)和小白抽取到的扑克牌(从左向右排列)

输出描述:

对于每一局,在开始和结束,分别输出{和}输出获胜的方法,回合策略的结尾输出一个空格。若存在多个获胜方法,请按字典序的升序输出。

示例1

输入:

3
123
3
123
321
45
67

输出:

{
d d l
d d r
}
{
l l l
r l l
}
{
}

暴力搜索可破。


import java.util.*;

public class Main {
    static List<String> res;
    static Queue<String> road;
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        int S = sc.nextInt();
        for (int i = 0; i < S; i++) {
            String nums1 = sc.next();
            String nums2 = sc.next();
            res = new ArrayList<>();
            road = new ArrayDeque<>();
            find(nums1, "", nums2);
            printResult(res);
        }
    }

    private static void find(String origin, String now, String target) {
        if (target.equals(now)) {
            if (origin.length() >= 0) {
                for (int i = 0; i < origin.length(); i++) {
                    road.offer("d");
                }
            }
            res.add(String.join(" ",road));
            return;
        }
        if (origin == null || origin.length() == 0) {
            return;
        }

        String left = String.valueOf(origin.charAt(0));
        String norigin = origin.substring(1);

        road.offer("d");
        find(norigin, now, target);
        road.poll();

        road.offer("l");
        find(norigin, left + now, target);
        road.poll();

        road.offer("r");
        find(norigin, now + left, target);
        road.poll();
    }

    private static void printResult(List<String> res) {
        System.out.println("{");
        if (res == null || res.size() == 0) {
            System.out.println("}");
            return;
        } else {
            Collections.sort(res, (o1, o2) -> o1.compareTo(o2));
            for (int i = 0; i < res.size(); i++) {
                String s = res.get(i);
                System.out.println(String.join(" ", s));
            }
        }
        System.out.println("}");
    }
}

第3道


扔n个般子,第i个骰子有可能投掷出Xi种等概率的不同的结果,数字从1到Xi。所有般子的结果的最大值将作为最终结果。求最终结果的期望。

输入描述:

第一行一个整数n,表示有n个骰子。(1<=n<=50)
第二行n个整数,表示每个骰子的结果数xi。(2<=Xi<=50)

输出描述:

输出最终结果的期望,保留两位小数

示例1

输入:

2
2 2

输出:

1.75

这道计算题的技巧是,如计算f(3),将f(2)、f(1)的概率也囊括了进来,从整体上再将先前计算的f(2)、f(1)减去。

import java.util.Arrays;
import java.util.HashMap;
import java.util.Scanner;

public class Main {
    static HashMap<Integer, Long> map;
    static int n;
    static int[] a;
    static double[] p;
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        n = sc.nextInt();
        a = new int[n];
        for (int i = 0; i < n; i++) {
            a[i] = sc.nextInt();
        }
        Arrays.sort(a);
        p = new double[a[a.length - 1] + 1];
        int begin = 0;
        for (int max = 1; max <= a[a.length - 1]; max++) {
            while (a[begin] < max)
                begin ++;
            double p_max = 1.0;
            for (int i = begin; i < n; i++) {
                p_max *= max / (double)a[i];
            }
            p_max -= Arrays.stream(p).sum();
            p[max] = p_max;
        }
        double EX = 0;
        for (int X = 1; X <= a[a.length - 1]; X++) {
            EX += X * p[X];
        }
        System.out.printf("%.2f",EX);
    }
}

第4道
在一块长为n,宽为m的场地上,有n X m个1 X 1的单元格。每个单元格上的数字就是按照从1到n和1到m中的数的乘积。具体如下:
n = 3, m = 3
1 2 3
2 4 6
3 6 9
给出一个查询的值K,求出按照这个方式列举的的数中第k大的值v例如上面的例子里,从大到小为(9,6,6,4,3,3,2,2,1)
k=1,v=9
K=2,v=6
K=3,v=6
...
k=8,v=2
k=9,V=1

输入描述:

只有一行是3个数n,m,k表示场地的宽高和需要查询的k。使用空格隔开

输出描述:

给出第k大的数的值。

示例1

输入:

3 3 4

输出:

4

备注:

【数据范围】
100%的效据
1 <= n,m <= 40000
1 <= k <= n*m
30%的数据
1 <= n, m <= 1000

原是LeetCode改编,668. 乘法表中第k小的数

public class Main {
    public static void main(String args[]) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int k = sc.nextInt();
        int low = 1, high = m * n;
        while (low < high) {
            int mid = (low + high) / 2;
            int cnt = 0;
            for (int i = 1; i <= n; i++) {
                cnt += (mid / i > m) ? 0 : m - mid / i;
            }
            if (cnt < k) high = mid;
            else low = mid + 1;
        }
        System.out.println(low);
    }
}

#拼多多##笔试题目#
全部评论
看牛客好多大佬3题左右,两题的我又凉凉了……但是周围也没几个人做超过两题啊。也可能牛客上敢说出来的都是大佬吧。太难了
点赞 回复 分享
发布于 2019-09-03 08:43
大佬看看这个代码没问题吧,第二题 DFS,加了个简单的剪枝 import sys def per(origin, target): for i in target: if i not in origin: return [] res = [] dfs(origin, target, [], "", res) return res def dfs(old, target, path, now, res): if not old: # 遍历结束 # 判断是否相等 if now == target: res.append(path.copy()) return if not is_in(now, target): # 未遍历结束 # 判断是否已经不相等 return cur = old[0] if cur not in target: path.append("d") dfs(old[1:], target, path, now, res) path.pop() else: path.append("d") dfs(old[1:], target, path, now, res) path.pop() path.append("l") dfs(old[1:], target, path, cur + now, res) path.pop() path.append("r") dfs(old[1:], target, path, now + cur, res) path.pop() def is_in(ls1, ls2): # 判断 ls1 是否为 ls2 的连续子集 str1 = "".join(map(str, ls1)) str2 = "".join(map(str, ls2)) return str1 in str2 if __name__ == "__main__": s = int(sys.stdin.readline().strip()) ans = "" for _ in range(s): origin = sys.stdin.readline().strip() target = sys.stdin.readline().strip() ans += "{\n" res = per(origin, target) res.sort() # print(res) if res: for each_res in res: ans += " ".join(each_res) + " \n" ans += "}\n" if ans: ans = ans[:-1] print(ans)
点赞 回复 分享
发布于 2019-09-03 12:40
有没有大佬用c++复盘的
点赞 回复 分享
发布于 2019-09-03 13:17
第三题的编程有问题,对于大的点数容易造成OOM
点赞 回复 分享
发布于 2019-09-03 16:00
第二题,代码有问题,例子过不了
点赞 回复 分享
发布于 2019-09-03 17:07
第二题可以这样 import java.util.*; public class Main {     static List<String> res;     static Deque<String> road;     public static void main(String args[]) {         Scanner sc = new Scanner(System.in);         int S = Integer.parseInt(sc.nextLine());         for (int i = 0; i < S; i++) {             String nums1 = sc.nextLine();             String nums2 = sc.nextLine();             res = new ArrayList<>();             road = new ArrayDeque<>();             find(nums1, "", nums2);             printResult(res);         }     }     private static void find(String origin, String now, String target) {         if (target.equals(now)) {             for (int i = 0; i < origin.length(); i++) {                 road.offerLast("d ");             }             res.add(String.join("", road));             for (int i = 0; i < origin.length(); i++) {                 road.pollLast();             }             return;         }         if (origin == null || origin.length() == 0 || now.length() >= target.length()) {             return;         }         String left = String.valueOf(origin.charAt(0));         String remain = origin.substring(1);         road.offerLast("d ");         find(remain, now, target);         road.pollLast();         road.offerLast("l ");         find(remain, left + now, target);         road.pollLast();         road.offerLast("r ");         find(remain, now + left, target);         road.pollLast();     }     private static void printResult(List<String> res) {         System.out.println("{");         for (String oneRes : res) {             System.out.println(oneRes);         }         System.out.println("}");     } }
点赞 回复 分享
发布于 2019-09-03 19:30
第一题python分号的输入,为什么我用split(';')不对呢?正确应该怎么输入呢?
点赞 回复 分享
发布于 2019-09-03 19:35
诸位大佬,请问为什么拼多多第三题这里说:"如计算f(3),将f(2)、f(1)的概率也囊括了进来,从整体上再将先前计算的f(2)、f(1)减去。",感觉不理解,请问有人能讲解一下吗?
点赞 回复 分享
发布于 2019-09-03 22:18

相关推荐

牛客5655:其他公司的面试(事)吗
点赞 评论 收藏
分享
牛舌:如果我不想去,不管对方给了多少,我一般都会说你们给得太低了。这样他们就会给下一个offer的人更高的薪资了。
点赞 评论 收藏
分享
10 64 评论
分享
牛客网
牛客企业服务