美团笔试 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; // 返回最大公约数 } }