得物笔试 得物秋招 得物笔试题 0914
笔试时间:2025年9月14日
往年笔试合集:
第一题:栈的统计
给定长度均为n的数组A和数组B,下标均为1到n。现有一个空栈S,小明可以进行两种操作:
- 当数组A不为空时,把数组A中下标最小的且尚未删除的数压入栈S中,然后从数组A中删除这个数。
- 当栈S不为空时,设当前栈S中元素个数为j,当前栈顶元素为x,则立刻获得x×B[j]的收益,然后把栈S的栈顶元素弹出。
小明的一种操作方案必须包含恰好2n次操作。求所有不同的操作方案的收益之和。
输入描述
输出描述
输出一个整数,表示所有不同的操作方案的收益之和。
样例输入
2
1 2
2 3
样例输出
14
样例中有2种操作方案:
- 操作1,操作1,操作2,操作2:收益为 3×2+2×1=8
- 操作1,操作2,操作1,操作2:收益为 2×1+2×2=6
总收益之和为 14。
参考题解
解题思路:
使用深度优先搜索(DFS)和回溯法,递归枚举所有可能的操作序列。维护当前路径的收益和路径数量,每次可以选择入栈或出栈操作,当完成n次入栈和n次出栈后,统计该路径的总收益。
C++:
#include <iostream> #include <vector> #include <stack> using namespace std; int n; vector<int> a, b; struct Result { long long totalBenefit; long long numWays; }; Result solve(int pushes, int pops, stack<int> stk) { if (pushes == n && pops == n) { return {0, 1}; } long long currentTotalBenefit = 0; long long currentNumWays = 0; if (pushes < n) { stk.push(a[pushes]); Result res = solve(pushes + 1, pops, stk); currentTotalBenefit += res.totalBenefit; currentNumWays += res.numWays; stk.pop(); } if (pops < pushes) { int topElement = stk.top(); stk.pop(); long long benefit = (long long)topElement * b[stk.size()]; Result res = solve(pushes, pops + 1, stk); currentTotalBenefit += res.totalBenefit + res.numWays * benefit; currentNumWays += res.numWays; stk.push(topElement); } return {currentTotalBenefit, currentNumWays}; } int main() { cin >> n; a.resize(n); b.resize(n); for (int i = 0; i < n; i++) { cin >> a[i]; } for (int i = 0; i < n; i++) { cin >> b[i]; } stack<int> emptyStack; Result finalResult = solve(0, 0, emptyStack); cout << finalResult.totalBenefit << endl; return 0; }
Java:
import java.util.Scanner; import java.util.Stack; public class Main { private static int n; private static int[] a; private static int[] b; static class Result { long totalBenefit; long numWays; Result(long totalBenefit, long numWays) { this.totalBenefit = totalBenefit; this.numWays = numWays; } } private static Result solve(int pushes, int pops, Stack<Integer> stack) { if (pushes == n && pops == n) { return new Result(0, 1); } long currentTotalBenefit = 0; long currentNumWays = 0; if (pushes < n) { stack.push(a[pushes]); Result res = solve(pushes + 1, pops, stack); currentTotalBenefit += res.totalBenefit; currentNumWays += res.numWays; stack.pop(); } if (pops < pushes) { int topElement = stack.pop(); long benefit = (long) topElement * b[stack.size()]; Result res = solve(pushes, pops + 1, stack); currentTotalBenefit += res.totalBenefit + res.numWays * benefit; currentNumWays += res.numWays; stack.push(topElement); } return new Result(currentTotalBenefit, currentNumWays); } public static void main(String[] args) { Scanner scanner = new Scanner(System.in); n = scanner.nextInt(); a = new int[n]; b = new int[n]; for (int i = 0; i < n; i++) { a[i] = scanner.nextInt(); } for (int i = 0; i < n; i++) { b[i] = scanner.nextInt(); } Result finalResult = solve(0, 0, new Stack<>()); System.out.println(finalResult.totalBenefit); } }
Python:
def solve(pushes, pops, stack, a, b, n): if pushes == n and pops == n: return (0, 1) current_total_benefit = 0 current_num_ways = 0 if pushes < n: stack.append(a[pushes]) res = solve(pushes + 1, pops, stack, a, b, n) current_total_benefit += res[0] current_num_ways += res[1] stack.pop() if pops < pushes: top_element = stack.pop() benefit = top_element * b[len(stack)] res = solve(pushes, pops + 1, stack, a, b, n) current_total_benefit += res[0] + res[1] * benefit current_num_ways += res[1] stack.append(top_element) return (current_total_benefit, current_num_ways) n = int(input()) a = list(map(int, input().split())) b = list(map(int, input().split())) result = solve(0, 0, [], a, b, n) print(result[0])
第二题:最小值
给你一个长度为n的数组A和一个长度为m的数组B,以及一个模数mod。你需要从数组A里选取一个数x,从数组B中选取一个数y,使得(x+y) mod mod的值是所有选取方式中最小的。
输入描述
输出描述
一个整数,表示求得的最小值。
样例输入
4 5 10
1 2 3 4
1 2 3 4 5
样例输出
0
参考题解
解题思路:
对数组B取模后排序,对于数组A中的每个元素a,在B中二分查找最接近mod-a的值。最优解只可能是B中大于等于target的最小值或小于target的最大值,分别计算并更新最小值。
C++:
#include <iostream> #include <vector> #include <algorithm> #include <climits> using namespace std; int lower_bound_custom(vector<long long>& arr, long long key) { int low = 0, high = arr.size(); while (low < high) { int mid = low + (high - low) / 2; if (arr[mid] >= key) { high = mid; } else {
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
2025 春招笔试合集 文章被收录于专栏
2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南