联想笔试 联想笔试题 0323
笔试时间:2025年03月23日
历史笔试传送门:
第一题
题目:苹果园
小明正在神奇苹果园里工作。这个苹果园里一共有棵神奇苹果树,编号从1到n,其中编号为i的苹果树初始有着ai个苹果,且保证ai >0。每天小明需要选择其中一棵还有苹果的苹果树上采摘,小明会将其上所有苹果都采摘下来,使得该树上苹果数量归零。采摘完成后,其他所有苹果树会受到惊吓,从而立刻使得它们树上的苹果数量翻倍。小明想要以最优方式采摘,使得最后能收集到的苹果数量最多。请你帮小明找到这样的方案。初始时在第1天,第i棵树上有ai个苹果,小明应当选择一颗采摘,而后其余苹果树的苹果数量翻倍,再到第2天循环往复直到第n天小明采摘完最后一颗非空苹果树。
输入描述
第一行一个整数n,表示苹果树数量。
第二行n个整数a1,a2,...an,ai表示编号为i的苹果树初始苹果数量。
输出描述
输出一个整数表示答案。因为结果可能较大,请输出结果100000007模的余数。
样例输入
2
1 2
样例输出
5
说明:
第一天采摘第1棵,获得1个苹果,另一棵上苹果树翻倍,变成了4。
第二天只有第2棵树非空,采摘获得4个苹果。
可以证明没有更优方案。
参考题解
贪心,每次摘最少的果子,就能使数量多的尽可能多翻倍。所以对数组排序,依次从小到大摘即可,过程中需要不断取模防止溢出。
C++:[此代码未进行大量数据的测试,仅供参考]
#include <bits/stdc++.h> using ll = long long; using namespace std; ll mod = 1e8 + 7; int main() { int n; cin >> n; vector<ll> a(n); for (auto &i : a) cin >> i; sort(begin(a), end(a)); ll res = 0; ll p = 1; for (auto &x : a) { res += x * p; res %= mod; p *= 2; p %= mod; } cout << res; }
Java:[此代码未进行大量数据的测试,仅供参考]
import java.util.*; public class Main { static final long MOD = 100000007; public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt(); long[] a = new long[n]; for (int i = 0; i < n; i++) { a[i] = sc.nextLong(); } Arrays.sort(a); long res = 0; long p = 1; for (long x : a) { res = (res + x * p % MOD) % MOD; p = (p * 2) % MOD; } System.out.println(res); } }
Python:[此代码未进行大量数据的测试,仅供参考]
MOD = 10**8 + 7 n = int(input()) a = list(map(int, input(
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
2025打怪升级记录,大厂笔试合集 C++, Java, Python等多种语言做法集合指南