🍭 大家好这里是清隆学长 ,一枚热爱算法的程序员
✨ 本系计划跟新各公司春秋招的笔试题
💻 ACM银牌🥈| 多次AK大厂笔试 | 编程一对一辅导
👏 感谢大家的订阅➕ 和 喜欢💗
📧 清隆这边最近正在收集近一年互联网各厂的笔试题汇总,如果有需要的小伙伴可以关注CSDN同名公主号领取,会在飞书进行同步的跟新。
文章目录
- 📖 写在前面
- 夏天要来了 秋招还会远吗?
- 🍊 01.LYA 的魔法宝石
- 问题描述
- 输入格式
- 输出格式
- 样例输入
- 样例输出
- 数据范围
- 题解
- 参考代码
- 🌲 02.卢小姐的布料选购计划
- 问题描述
- 输入格式
- 输出格式
- 样例输入
- 样例输出
- 数据范围
- 题解
- 参考代码
- 🎧 03.LYA 的珍珠项链
- 问题描述
- 输入格式
- 输出格式
- 样例输入
- 样例输出
- 数据范围
- 题解
- 参考代码
- 🎀 写在最后
- 🛖 这里介绍一下咱们的笔试打卡小屋
- 🥰 打卡奖励
- 🕰 每日学习安排
- 📖 打卡小屋涉及题型
- 基础算法
- 基础数据结构
- 搜索
- 动态规划 & 贪心 & 数论
📖 写在前面
夏天要来了 秋招还会远吗?
前不久春招也算是圆满结束咯,大家有拿到心仪的 offer吗?
接下来互联网的秋招也快来啦,小伙伴们有开始准备了吗?
本次给大家带来24届秋招 阿里系 的笔试题目三语言解析(Java/Python/Cpp)
文末有清隆学长的笔试陪伴打卡小屋活动介绍:
✨丰富的打卡奖励等你来领哦,大厂笔试题汇总,笔试面试经验贴,算法笔试模版…
💽 有兴趣的小伙伴们也可以了解一下,不要错过啦~
🍊 01.LYA 的魔法宝石
问题描述
LYA 是一位热爱收藏魔法宝石的女孩。她希望收集 n n n 颗宝石,并且要求这些宝石的魔法值两两不相等。此外,所有宝石的魔法值的最大公约数必须为 k k k。
为了尽可能节省购买成本,LYA 希望选择魔法值之和最小的宝石组合。请你帮助 LYA 计算并输出宝石魔法值之和的最小值。
输入格式
输入包含两个正整数 n n n 和 k k k,分别表示宝石的数量和魔法值的最大公约数。
输出格式
输出一个正整数,表示满足条件的宝石魔法值之和的最小值。
样例输入
3 2
样例输出
12
数据范围
1 ≤ n , k ≤ 1 0 5 1 \leq n, k \leq 10^5 1≤n,k≤105
题解
本题可以通过构造法来解决。为了让宝石的魔法值之和最小,我们可以将魔法值构造为 k k k 的倍数,并且按照从小到大的顺序选择。
具体步骤如下:
- 初始化结果变量 r e s res res 为 0 0 0,表示宝石魔法值之和。
- 从
1
1
1 到
n
n
n 遍历每个宝石:
- 计算当前宝石的魔法值 t e m p = i × k temp = i \times k temp=i×k。
- 将 t e m p temp temp 累加到结果变量 r e s res res 中。
- 输出结果变量 r e s res res 的值。
时间复杂度:
O
(
n
)
O(n)
O(n),其中
n
n
n 为宝石的数量。
空间复杂度:
O
(
1
)
O(1)
O(1)。
参考代码
- Python
n, k = map(int, input().split())
res = 0
for i in range(1, n + 1):
temp = i * k
res += temp
print(res)
- Java
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
int n = in.nextInt();
int k = in.nextInt();
long res = 0;
for (int i = 1; i <= n; i++) {
long temp = i * k;
res += temp;
}
System.out.println(res);
}
}
- Cpp
#include <iostream>
using namespace std;
int main() {
int n, k;
cin >> n >> k;
long long res = 0;
for (int i = 1; i <= n; i++) {
long long temp = i * k;
res += temp;
}
cout << res << endl;
return 0;
}
🌲 02.卢小姐的布料选购计划
问题描述
卢小姐是一位服装设计师,她计划从一家面料商那里购买一段布料用于设计新款连衣裙。商家提供了一卷总长为 n n n 米的布料,但其中只有某些区间的布料质地符合要求。
商家允许卢小姐从这卷布料中选择一段长度为 k k k 米的连续区间购买。卢小姐希望在选定的区间内,符合要求的布料段总长度尽可能长。请你帮助卢小姐计算,最优方案下可以购得多少米符合要求的布料。
输入格式
第一行输入三个正整数 n , m , k n,m,k n,m,k,分别代表布卷的总长度、布卷上符合要求的布料段数量以及卢小姐计划购买的布料长度。
接下来的 m m m 行,每行输入两个正整数 l i , r i l_i,r_i li,ri,表示第 i i i 段符合要求的布料的起始位置和终止位置(单位:米)。
输出格式
输出一个整数,表示最优方案下可以购得的符合要求的布料总长度。
样例输入
10 3 6
1 3
4 5
7 9
样例输出
4
数据范围
- 1 ≤ k ≤ n ≤ 1 0 9 1 \leq k \leq n \leq 10^9 1≤k≤n≤109
- 1 ≤ m ≤ 1 0 5 1 \leq m \leq 10^5 1≤m≤105
- 0 ≤ l i < r i ≤ n 0 \leq l_i < r_i \leq n 0≤li<ri≤n
- 符合要求的布料段之间互不重叠。
题解
本题可以使用双指针滑动窗口的方法求解。我们可以枚举购买布料的左端点,并维护一个右端点,使得当前窗口内的布料长度不超过 k k k。在枚举过程中,我们统计窗口内符合要求的布料段长度之和,并更新答案。
具体步骤如下:
- 将所有符合要求的布料段按照起始位置从小到大排序。
- 初始化左右指针 l e f t left left 和 r i g h t right right,表示当前枚举的区间范围。
- 遍历布料段,将右指针 r i g h t right right 不断右移,直到当前区间长度超过 k k k 或遍历完所有布料段。
- 统计当前区间内符合要求的布料段长度之和 c o v e r cover cover,更新答案。
- 如果右指针 r i g h t right right 已经到达最后一个布料段,直接更新答案;否则,计算当前区间右端点与下一个布料段左端点之间的空白部分长度 r e m a i n remain remain,更新答案为 m a x ( a n s , c o v e r + r e m a i n ) max(ans,cover+remain) max(ans,cover+remain)。
- 将左指针 l e f t left left 右移一个布料段,同时将 c o v e r cover cover 减去对应的布料段长度,继续枚举下一个区间。
时间复杂度为 O ( m log m ) O(m \log m) O(mlogm),其中排序的时间复杂度为 O ( m log m ) O(m \log m) O(mlogm),双指针遍历的时间复杂度为 O ( m ) O(m) O(m)。空间复杂度为 O ( m ) O(m) O(m)。
参考代码
- Python
class Solution:
def maxCoverLength(self, n: int, m: int, k: int, segments: List[List[int]]) -> int:
segments.sort()
ans = cover = 0
left = right = 0
while right < m:
while right < m and segments[right][1] - segments[left][0] <= k:
cover += segments[right][1] - segments[right][0]
right += 1
if right == m:
ans = max(ans, cover)
else:
remain = max(0, segments[left][0] + k - segments[right][0])
ans = max(ans, cover + remain)
cover -= segments[left][1] - segments[left][0]
left += 1
return ans
- Java
class Solution {
public int maxCoverLength(int n, int m, int k, int[][] segments) {
Arrays.sort(segments, (a, b) -> a[0] - b[0]);
int ans = 0, cover = 0;
int left = 0, right = 0;
while (right < m) {
while (right < m && segments[right][1] - segments[left][0] <= k) {
cover += segments[right][1] - segments[right][0];
right++;
}
if (right == m) {
ans = Math.max(ans, cover);
} else {
int remain = Math.max(0, segments[left][0] + k - segments[right][0]);
ans = Math.max(ans, cover + remain);
}
cover -= segments[left][1] - segments[left][0];
left++;
}
return ans;
}
}
- Cpp
class Solution {
public:
int maxCoverLength(int n, int m, int k, vector<vector<int>>& segments) {
sort(segments.begin(), segments.end());
int ans = 0, cover = 0;
int left = 0, right = 0;
while (right < m) {
while (right < m && segments[right][1] - segments[left][0] <= k) {
cover += segments[right][1] - segments[right][0];
right++;
}
if (right == m) {
ans = max(ans, cover);
} else {
int remain = max(0, segments[left][0] + k - segments[right][0]);
ans = max(ans, cover + remain);
}
cover -= segments[left][1] - segments[left][0];
left++;
}
return ans;
}
};
🎧 03.LYA 的珍珠项链
问题描述
LYA 有一条由 n n n 颗不同颜色珍珠串成的项链。她想通过改变其中某一颗珍珠的颜色来提升项链的美观度。根据专家的建议,项链的美观度等于任意连续的珍珠子串中,各颜色出现次数的最大值。
现在给定项链上每颗珍珠的颜色,以及 LYA 可以将某颗珍珠改变成的目标颜色,请你计算改变后项链的最大美观度是多少?
输入格式
第一行包含一个正整数 t t t,表示项链的条数。
接下来对于每条项链,第一行包含两个正整数 n n n 和 c c c,分别表示项链的长度和目标颜色。第二行包含 n n n 个正整数 a 1 , a 2 , ⋯ , a n a_1, a_2, \cdots, a_n a1,a2,⋯,an,表示初始时项链上每颗珍珠的颜色。
输出格式
对于每条项链,输出一行一个整数,表示改变后项链的最大美观度。
样例输入
3
5 10
5 -1 -5 -3 2
2 -3
-5 -2
6 10
4 -2 -11 -1 4 -1
样例输出
15
-2
15
数据范围
- 1 ≤ t ≤ 1 0 5 1 \leq t \leq 10^5 1≤t≤105
- 1 ≤ n ≤ 2 × 1 0 5 1 \leq n \leq 2 \times 10^5 1≤n≤2×105
- − 1 0 9 ≤ c , a i ≤ 1 0 9 -10^9 \leq c, a_i \leq 10^9 −109≤c,ai≤109
- 所有项链的总长度不超过 2 × 1 0 5 2 \times 10^5 2×105
题解
本题可以使用动态规划求解。设 d p [ i ] [ 0 ] dp[i][0] dp[i][0] 表示不改变第 i i i 颗珍珠颜色的最大美观度, d p [ i ] [ 1 ] dp[i][1] dp[i][1] 表示将第 i i i 颗珍珠改变为目标颜色的最大美观度。则有以下状态转移方程:
d p [ i ] [ 0 ] = max ( d p [ i − 1 ] [ 0 ] + a i , a i ) d p [ i ] [ 1 ] = max ( d p [ i − 1 ] [ 0 ] + c , c , d p [ i − 1 ] [ 1 ] + a i , a i ) \begin{aligned} dp[i][0] &= \max(dp[i-1][0] + a_i, a_i) \\ dp[i][1] &= \max(dp[i-1][0] + c, c, dp[i-1][1] + a_i, a_i) \end{aligned} dp[i][0]dp[i][1]=max(dp[i−1][0]+ai,ai)=max(dp[i−1][0]+c,c,dp[i−1][1]+ai,ai)
最终答案为 max ( d p [ n − 1 ] [ 0 ] , d p [ n − 1 ] [ 1 ] ) \max(dp[n-1][0], dp[n-1][1]) max(dp[n−1][0],dp[n−1][1])。
时间复杂度 O ( n ) O(n) O(n),空间复杂度 O ( n ) O(n) O(n)。
参考代码
- Python
t = int(input())
for _ in range(t):
n, c = map(int, input().split())
a = list(map(int, input().split()))
dp = [[0] * 2 for _ in range(n)]
dp[0][0] = a[0]
dp[0][1] = c
res = max(dp[0])
for i in range(1, n):
dp[i][0] = max(dp[i-1][0] + a[i], a[i])
dp[i][1] = max(dp[i-1][0] + c, c, dp[i-1][1] + a[i], a[i])
res = max(res, dp[i][0], dp[i][1])
print(res)
- Java
import java.util.*;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int t = sc.nextInt();
while (t-- > 0) {
int n = sc.nextInt(), c = sc.nextInt();
int[] a = new int[n];
for (int i = 0; i < n; i++) {
a[i] = sc.nextInt();
}
System.out.println(maxBeauty(a, c));
}
}
private static long maxBeauty(int[] a, int c) {
int n = a.length;
long[][] dp = new long[n][2];
dp[0][0] = a[0];
dp[0][1] = c;
long res = Math.max(dp[0][0], dp[0][1]);
for (int i = 1; i < n; i++) {
dp[i][0] = Math.max(dp[i-1][0] + a[i], a[i]);
dp[i][1] = Math.max(Math.max(dp[i-1][0] + c, c),
Math.max(dp[i-1][1] + a[i], a[i]));
res = Math.max(res, Math.max(dp[i][0], dp[i][1]));
}
return res;
}
}
- Cpp
#include <iostream>
#include <vector>
using namespace std;
long maxBeauty(vector<int>& a, int c) {
int n = a.size();
vector<vector<long>> dp(n, vector<long>(2));
dp[0][0] = a[0];
dp[0][1] = c;
long res = max(dp[0][0], dp[0][1]);
for (int i = 1; i < n; i++) {
dp[i][0] = max(dp[i-1][0] + a[i], (long)a[i]);
dp[i][1] = max(max(dp[i-1][0] + c, (long)c),
max(dp[i-1][1] + a[i], (long)a[i]));
res = max(res, max(dp[i][0], dp[i][1]));
}
return res;
}
int main() {
int t;
cin >> t;
while (t--) {
int n, c;
cin >> n >> c;
vector<int> a(n);
for (int i = 0; i < n; i++) {
cin >> a[i];
}
cout << maxBeauty(a, c) << endl;
}
return 0;
}
🎀 写在最后
🛖 这里介绍一下咱们的笔试打卡小屋
✨ 打卡小屋旨在陪伴大家,养成每日学习的好习惯。在这里,你可以:
- 🤝 与备战笔试的小伙伴相识,找到志同道合的学习小组
- 📝 通过写题解,巩固做题思路,养成良好的记录习惯
- 💡 系统掌握常考算法和数据结构,了解互联网笔试难度
- 🎁 坚持打卡,获得丰厚奖励,激励自己持之以恒
🥰 打卡奖励
打卡时长 | 奖励内容 |
---|---|
7天 | 任选一家最新互联网笔试真题 x 1 (价值29.9r) |
14天 | 任选一家最新互联网笔试真题 x 3 + 笔试面试经验贴 |
21天 | 任选一家最新互联网笔试真题 x 5 + 清隆三语言算法模版 |
28天 | 最新互联网大厂笔试真题汇总(价值199r) + 华为OD机试训练营 (价值89r) |
7天打卡即可值回票价,心动不如行动!
🕰 每日学习安排
小屋将在每日上午发放打卡题目,包括:
- 一道算法模版题,帮助大家掌握常用算法套路
- 根据算法模版,精选一道对应的大厂笔试真题,巩固算法应用
让我们一起直击笔试重点,攻克常考题型!
📖 打卡小屋涉及题型
小屋从零基础出发,涵盖笔试常考知识点:
基础算法
- 自定义排序
- 二分
- 前缀和
- 差分
- 双指针
基础数据结构
- 栈 & 单调栈
- 队列 & 单调队列
- 并查集
- 优先队列(堆)
搜索
- DFS & BFS 基础应用
- 树的遍历
- 基础图论
动态规划 & 贪心 & 数论
- 快速幂
- 组合数
- 质数 & 因数
- 位运算
- 基础动态规划
- 常见贪心