美团笔试 2022.3.19

只ac了前两道,后两道有corner case没考虑到。大家交流一下,顺便求正确做法!!!
------------------------------------------------------------------------------------------------------------------
第三题已更正,我确信是对的
第四题已更正,参照一位dalao做法 https://www.nowcoder.com/discuss/868013?type=2
第一题
import java.util.Scanner;

public class Solution1 {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int productNum = sc.nextInt();
        int[][] product = new int[productNum][2];
        for (int i = 0; i < productNum; i++) {
            product[i][0] = sc.nextInt();
        }
        for (int i = 0; i < productNum; i++) {
            product[i][1] = sc.nextInt();
        }
        int princpleNum = sc.nextInt();
        int[][] princple = new int[princpleNum][2];
        for (int i = 0; i < princpleNum; i++) {
            princple[i][0] = sc.nextInt();
        }
        for (int i = 0; i < princpleNum; i++) {
            princple[i][1] = sc.nextInt();
        }
        System.out.println(getOutPut(productNum, product, princpleNum, princple));
    }

    private static String getOutPut(int productNum, int[][] product, int princpleNum, int[][] princple) {
        StringBuilder res = new StringBuilder();
        int productRawPrice = 0;
        int productMinusPrice = 0;
        int princplePtr = -1;
        for (int ptr = 0; ptr < productNum; ptr++) {
            productRawPrice += product[ptr][0];
            productMinusPrice += product[ptr][1];
            int tmpPrice = productRawPrice;
            while (princplePtr + 1 < princpleNum && productRawPrice >= princple[princplePtr + 1][0]) {
                princplePtr++;
            }
            if (princplePtr > -1) {
                tmpPrice -= princple[princplePtr][1];
            }
            if (tmpPrice > productMinusPrice) {
                res.append('Z');
            } else if (tmpPrice < productMinusPrice) {
                res.append('M');
            } else {
                res.append('B');
            }

        }

        return res.toString();
    }

}

第二题
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Solution2 {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int strLen = sc.nextInt();
        int operation = sc.nextInt();
        sc.nextLine();
        String str = sc.nextLine();
        System.out.println(operateStr(str, operation));
    }

    private static String operateStr(String str, int operation) {
        if (operation == 1) {
            return encodeStr(str);
        } else {
            return decodeStr(str);
        }
    }

    private static String decodeStr(String str) {
        List<Character> output = new ArrayList<>();
        char[] ch = str.toCharArray();
        int strLen = str.length();
        for (int i = strLen - 1; i > -1; i--) {
            int index = (output.size() + 1 + 1) / 2 - 1;
            output.add(index, ch[i]);
        }
        StringBuilder sb = new StringBuilder();
        for (char tmpChar : output) {
            sb.append(tmpChar);
        }
        return sb.toString();
    }

    private static String encodeStr(String str) {
        int strLen = str.length();
        List<Character> input = new ArrayList<>();
        for (int i = 0; i < strLen; i++) {
            input.add(str.charAt(i));
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < strLen; i++) {
            int tmpLen = input.size();
            int index = (tmpLen + 1) / 2 - 1;
            sb.append(input.remove(index));
        }
        return sb.toString();
    }
}

第三题
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Scanner;

public class Solution3 {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        long fileNum = sc.nextLong();

        int changedFileNumOnBook = sc.nextInt();
        int changedFileNumOnCom = sc.nextInt();
        long[][] bookChange = new long[changedFileNumOnBook][2];
        long[][] comChange = new long[changedFileNumOnCom][2];
        for (int i = 0; i < changedFileNumOnBook; i++) {
            bookChange[i][0] = sc.nextLong();
        }
        for (int i = 0; i < changedFileNumOnBook; i++) {
            bookChange[i][1] = sc.nextLong();
        }
        for (int i = 0; i < changedFileNumOnCom; i++) {
            comChange[i][0] = sc.nextLong();
        }
        for (int i = 0; i < changedFileNumOnCom; i++) {
            comChange[i][1] = sc.nextLong();
        }
        System.out.println(getConflictFileNum(changedFileNumOnBook, changedFileNumOnCom, bookChange, comChange));
    }

    private static int getConflictFileNum(int changedFileNumOnBook, int changedFileNumOnCom, long[][] bookChange, long[][] comChange) {
        Arrays.sort(bookChange, (o1, o2) -> {return (int) (o1[0] == o2[0] ? o1[1] - o2[1] : o1[0] - o2[0]);});
        Arrays.sort(comChange, (o1, o2) -> {return (int) (o1[0] == o2[0] ? o1[1] - o2[1] : o1[0] - o2[0]);});
        bookChange = merge(bookChange);
        comChange = merge(comChange);
        changedFileNumOnBook = bookChange.length;
        changedFileNumOnCom = comChange.length;
        int res = 0;
        int bookPtr = 0;
        int comPtr = 0;
        while (bookPtr < changedFileNumOnBook && comPtr < changedFileNumOnCom) {
            long[] book = bookChange[bookPtr];
            long[] com = comChange[comPtr];
            if (book[1] > com[1]) {
                if (book[0] <= com[0]) {
                    res += com[1] - com[0] + 1;
                } else if (book[0] <= com[1]) {
                    res += com[1] - book[0] + 1;
                }
                comPtr++;
            } else {
                if (com[0] <= book[0]) {
                    res += book[1] - book[0] + 1;
                } else if (com[0] <= book[1]) {
                    res += book[1] - com[0] + 1;
                }
                bookPtr++;
            }
        }

        return res;
    }

    private static long[][] merge(long[][] change) {
        List<long[]> ls = new ArrayList<>();
        int len = change.length;
        if (len == 0) {
            return change;
        }
        ls.add(change[0]);
        for (int i = 1; i < len; i++) {
            long[] tmp = change[i];
            long[] pre = ls.get(ls.size() - 1);
            if (tmp[0] > pre[1]) {
                ls.add(tmp);
            } else {
                pre[1] = Math.max(tmp[1], pre[1]);
            }
        }
        return ls.toArray(new long[0][0]);
    }


}

第四题
import java.util.Arrays;
import java.util.Scanner;

public class Solution4 {

    private static long maxValue = 0;
    private static int possNum = 0;

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int ballNum = sc.nextInt();
        int k1 = sc.nextInt();
        int k2 = sc.nextInt();
        int[] ball = new int[ballNum];
        for (int i = 0; i < ballNum; i++) {
            ball[i] = sc.nextInt();
        }
        computeCombination(ball, k1, k2);
        System.out.print(maxValue + " " + possNum);
    }


    private static void computeCombination(int[] ball, int k1, int k2) {
        int divisor = (k1 * k2) / maxCommonDivisor(k1, k2);
        int len = ball.length;
        //从前i个数中选取一个组合,组合的数字和为n,n必须满足余divisor为j。valueDp[i][j]记录了最大的n,timesDp[i][j]记录了n为valueDp[i][j]的组合数
        //为什么要余divisor?已知preNum,newNum是使得preNum % k1 == num % k1 && preNum % k2 == num % k2成立的num的最小值,那么:preNum % divisor == newNum
        int[][] valueDp = new int[len + 1][divisor];
        int[][] timesDp = new int[len + 1][divisor];
        for (int i = 0; i <= len; i++) {
            for (int j = 0; j < divisor; j++) {
                //必须初始化为极小的数
                valueDp[i][j] = -0x3f3f3f3f;
            }
        }
        valueDp[0][0] = 0;
        timesDp[0][0] = 1;
        for (int i = 1; i <= len; i++) {
            for (int j = 0; j < divisor; j++) {
                valueDp[i][j] = Math.max(valueDp[i][j], valueDp[i - 1][j]);
                //确保余数为正数
                int index = ((j + ball[i - 1]) % divisor + divisor) % divisor;
                if (valueDp[i - 1][j] != -0x3f3f3f3f) {
                    valueDp[i][index] = Math.max(valueDp[i][index], valueDp[i - 1][j] + ball[i - 1]);
                }
            }
            for (int j = 0; j < divisor; j++) {
                if (valueDp[i][j] == valueDp[i - 1][j]) {
                    timesDp[i][j] = (timesDp[i][j] + timesDp[i - 1][j]) % 998244353;
                }
                int index = ((j + ball[i - 1]) % divisor + divisor) % divisor;
                if (valueDp[i][index] == valueDp[i - 1][j] + ball[i - 1]) {
                    timesDp[i][index] = (timesDp[i][index] + timesDp[i - 1][j]) % 998244353;
                }
            }
        }
        for (int j = 0; j < divisor; j++) {
            if (j % k1 == 0 && j % k2 != 0) {
                if (valueDp[len][j] > maxValue) {
                    maxValue = valueDp[len][j];
                    possNum = timesDp[len][j];
                }
            }
        }

    }

    //求最大公约数
    public static int maxCommonDivisor(int m, int n) {
        if (m < n) {            //保证被除数大于除数
            int temp = m;
            m = n;
            n = temp;
        }

        while (m % n != 0) {    //在余数不能为0时,进行循环
            int temp = m % n;
            m = n;
            n = temp;
        }
        return n;               // 返回最大公约数
    }

}



#美团笔试##笔试题目##美团#
全部评论
第三题可以考虑差分呀
1 回复 分享
发布于 2022-03-19 15:45
第三题用bitmap hh,第四题dp压缩 https://leetcode-cn.com/problems/target-sum/
点赞 回复 分享
发布于 2022-03-19 12:19
部分通过有分嘛
点赞 回复 分享
发布于 2022-03-19 12:25
第四题用dp
点赞 回复 分享
发布于 2022-03-19 13:45
大佬,想请问一下,为什么第三题要merge(bookChange)和merge(comChange)呢?同一台电脑上修改的也可能会出现区间重叠吗?
点赞 回复 分享
发布于 2022-03-19 15:33

相关推荐

01-27 09:51
邢台学院 C++
点赞 评论 收藏
分享
头像
2024-12-14 23:12
携程_移动安全研发
点赞 评论 收藏
分享
评论
2
15
分享

创作者周榜

更多
牛客网
牛客企业服务