8.26-美团-笔试
只做出了三道半。。。感觉美团换成牛客平台后,特别针对Java选手,同样的思路cpp、py都能过。。。
第一题:小美种果树
当时直接模拟就好了,我在这边找规律,做了快半个小时
public static void main(String[] args) { Scanner sc = new Scanner(System.in); int x = sc.nextInt(); int y = sc.nextInt(); int z = sc.nextInt(); int yu = z%(3*x+y); //一个周期三天 成长值3*x+y , int ans =0; if(yu==0) { ans = 3* (z/(3*x+y)); }else { if(yu<x+y){ ans = 3* (z/(3*x+y))+1; } else if(yu<2*x+y){ ans = 3* (z/(3*x+y))+2; }else { ans = 3* (z/(3*x+y))+3; } } System.out.println(ans); }
第二题:小美结账
直接模拟
public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int m = sc.nextInt(); long a[] = new long[m + 2]; for (int i = 1; i <= n; i++){ int k = sc.nextInt(); int c = sc.nextInt(); int avg = (c+k-1)/k;//向上取整 for (int j = 1; j <= k-1; j++){ int id = sc.nextInt(); a[id] += avg; } } for (int i = 1; i <= m; i++){ if(i==1){ System.out.print(a[i]); }else { System.out.print(" "); System.out.print(a[i]); } } System.out.println(""); }
第三题:小美的游戏
小美有一个长度为n的数组,她最多可以进行k次操作,每次操作如下:
- 选择两个整数i,j(1<=i<j<=n)
- 选择两个整数x,y,使得x*y=ai*aj
- 将ai替换为x,将aj替换为y
她希望最多进行k次操作之后,最后数组中的元素的总和尽可能大。
思路:堆模拟。找到堆中最大的两个元素相乘,再往堆里加入相乘的值和1,循环k次即可。
static final int MOD = (int) 1e9 + 7; public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); int k = sc.nextInt(); PriorityQueue<BigDecimal> pq = new PriorityQueue<>((a, b) -> b.compareTo(a)); for (int i = 0; i < n; i++) { long x = sc.nextInt(); pq.offer(BigDecimal.valueOf(x)); } BigDecimal ans = BigDecimal.valueOf(0); while (k-- > 0) { BigDecimal x = pq.poll(), y = pq.poll(); pq.offer(x.multiply(y)); pq.offer(BigDecimal.valueOf(1)); } while (!pq.isEmpty()) { ans = ans.add(pq.poll()); } System.out.println(ans.divideAndRemainder(BigDecimal.valueOf(MOD))[1]); }
第四题:小美的数组重排
小美有两个长度为n的数组a和b。
小美想知道,能不能通过重排a数组使得对于任意1<=i<=n,1<=ai+bi<=m?
将会有q次询问。
思路:要想满足题目的要求,对于数组a的最小值,如果跟数组b的最大值进行合并,假设结果不满足,那就肯定是不可能的了,否则可以考虑次小值和次大值进行分配,以此类推,只需要将a数组正向排序,b数组逆向排序即可。
static final int N = 510; public static void main(String[] args) { Scanner sc = new Scanner(System.in); int q = sc.nextInt(); while (q-- > 0) { int n = sc.nextInt(); int m = sc.nextInt(); int[] a = new int[n]; int[] b = new int[n]; for (int i = 0; i < n; i++) { a[i] = sc.nextInt(); } for (int i = 0; i < n; i++) { b[i] = sc.nextInt(); } Arrays.sort(a); Arrays.sort(b); boolean flag = true; for (int i = 0, j = n - 1; i < n; i++, j--) { if (!(a[i] + b[j] >= 1 && a[i] + b[j] <= m)) { flag = false; break; } } System.out.println(flag ? "YES" : "NO"); } }
第五题:平均数为k的最长连续子数组
给定n个正整数组成的数组,求平均数正好等于k 的最长连续子数组的长度。
如果不存在任何一个连续子数组的平均数等于k,则输出-1。
否则输出平均数正好等于k的最长连续子数组的长度。
思路:思维题+哈希表模拟。
平均数比较难处理,我们不妨将原数组中每个元素都-k,这样问题转换成找到和为0的最长子数组。
public static void main(String[] args) { Scanner scanner = new Scanner(System.in); int n = scanner.nextInt(); int k = scanner.nextInt(); int[] a = new int[n]; for (int i = 0; i < n; i++) { a[i] = scanner.nextInt() - k; } int res = 0; HashMap<Integer, Integer> occ = new HashMap<>(); occ.put(0, -1); int tmp = 0; for (int i = 0; i < n; i++) { tmp += a[i]; if (occ.containsKey(tmp)) { res = Math.max(res, i - occ.get(tmp)); } if (!occ.containsKey(tmp)) { occ.put(tmp, i); } } System.out.println(res); }