美团|秋招|后端|2022.08.13|笔试第二场
15428
2022.08.13
2022.08.14
发布于 未知归属地

前言

秋招第二场的笔试,下午4点开始的;投的后端,已经做的是美团的第二次笔试了。(上一次笔试是春招的最后一场)
和上次一样,这次的笔试题目还是简单的。

题目

  1. 骑手有 n 个订单,每个订单需要时间 t 配送,每个订单有一个截止时间;骑手可以使用技能瞬间配送完成,问最少需要使用几次技能才能把所有订单准时送达。
    1 <= n <= 1e5, 1 <= t <= 100, 订单的送达时间介于[1, 1e7]之间
  2. n * m 的房间,一个扫地机器人初始时给第一行第一列的格子打扫干净了。现在给一连串的指令,上下左右移动(移动到哪里,哪里就打扫干净);假如房间所有地方都干净了,输出第几条指令之后就干净了;否则,输出没有干净的地方的数量。
    保证2 <= n, m <= 100, 指令长度 <= 100000
  3. 两个人玩扑克,有 n 张牌,两个人依次从牌顶拿牌放到牌底,然后拿出牌顶的牌,记下数字;如此反复,直到所有牌都被拿走,记下了 n 个数字,现在需要根据这 n 个数字输出原来牌的顺序(从牌顶到牌底)。我是直接逆推的。
    1<=n<=100000
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int[] nums = new int[n];
		for (int i = 0; i < n; ++i) {
			nums[i] = in.nextInt();
		}
		if (n < 3) {
			for (int i = 0; i < n; ++i) {
				System.out.print(nums[i] + " ");
			}
			return;
		}
		// int[] res = new int[n];

		LinkedList<Integer> linkedList = new LinkedList<>();


		for (int i = n - 1; i >= 0; --i) {
			linkedList.addFirst(nums[i]);
			linkedList.addFirst(linkedList.removeLast());
			linkedList.addFirst(linkedList.removeLast());
		}

		// 题目操作顺序:
		//for (int i = 0; i < n; ++i) {
		//	linkedList.addLast(linkedList.removeFirst());
		//	linkedList.addLast(linkedList.removeFirst());
		//	res[i] = linkedList.removeFirst();
		//	System.out.print(res[i] + " ");
		//}

		for (Integer integer : linkedList) {
			System.out.print(integer + " ");
		}
	}
  1. 给一个长度为n的序列a[1], a[2], …, a[n],请问有多少个三元组(i,j,k)满足i<j<k且a[i]-a[j]=2a[j]-a[k]?输出符合要求的三元组的数量。我是想了想枚举+map,最后拿到 91%的通过率。正确的答案还得大佬了,我是直接上暴力了。
    1<=n<=4000, 0<=a[i]<=1000000
	public static void main(String[] args) {
		// a[i] = 3a[j] - a[k]
		// 枚举 a[i] 和 a[j] ,算出 a[k] = 3a[j] - a[i], map 中找 ?
		// On^3, 91%
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		HashMap<Integer, List<Integer>> map = new HashMap<>();
		int[] nums = new int[n];
		int num;
		for (int i = 0; i < n; ++i) {
			num = in.nextInt();
			nums[i] = num;
			List<Integer> index = map.getOrDefault(num, new ArrayList<>());
			index.add(i);
			map.put(num, index);
		}

		int res = 0;
		for (int i = 0; i < n; ++i) {
			int num1 = nums[i];
			for (int j = i + 1; j < n; ++j) {
				int target = ((nums[j] << 1) + nums[j]) - num1;
				List<Integer> index = map.get(target);
				if (index != null) {
					for (Integer k : index) {
						if (k > j) {
							++res;
						}
					}
				}
			}
		}
		System.out.println(res);
	}
  1. 给一棵有n个节点的二叉树,节点的编号从1到n。该二叉树的根节点为节点1,左儿子为节点2k,右儿子为节点2k+1,每个结点上都有钱(权值),每次选择左儿子或者右儿子向下走,直到走到叶子节点停止(最大路径值问题,利用递归),输出最多能够获得的钱。
    1 <= n <= 100000,我记得在力扣上做过类似的,是这一道题124. 二叉树中的最大路径和。不同的是,力扣上的还有负值,但是解决方法几乎一样。
评论 (60)