程序员基德 level
获赞
234
粉丝
285
关注
3
看过 TA
1498
中国科学技术大学
2026
C++
IP属地:浙江
热爱算法的程序员
私信
关注
------------------------------------题目一:题目大意:有 n (1 <= n <= 2e5) 颗宝石,每颗有能量值 ai (-n <= ai <= n)。你可以执行任意次“融合”操作:选择两颗宝石 i 和 j,将 j 的能量转移给 i (ai = ai + aj, aj = 0)。目标是最大化所有位置的前缀最大能量值之和,即 sum(max(a1, ..., ai)) for i=1 to n。(T 组数据, 1 <= T <= 1e4)解法思路:关键在于理解融合操作的本质是能量的自由分配。为了最大化前缀最大值之和,最优策略是创造一个尽可能大的数,并放在首位。如果数组中存在正数,就把所有正能量的宝石融合到第一颗上,使其能量变为所有正数之和,其余位置变为0或负数。这样每个前缀的最大值都是这个正数之和。如果所有宝石能量都是非正数,若 n>1,则可以通过融合操作造出一个0,使前缀最大值变为0;若 n=1,则无法操作,答案就是其本身的负能量值。------------------------------------题目二:题目大意:在一片 n x n (2 <= n, m <= 1e6) 的森林中,有 m 名探险者和 n 个救援站。救援站位于对角线 (i, i) 上,每个站只能救一人。探险者会去距离自己最近(曼哈顿距离)的救援站。如果有多个最近的,他们会协调分配以最大化获救人数。求最多能获救的人数。解法思路:此题可转化为区间选点问题。对于一个在 (x, y) 的探险者,其到对角线上救援站 (k, k) 的曼哈顿距离为 |x-k| + |y-k|。可以发现,当 k 落在 [min(x,y), max(x,y)] 区间内时,距离是最小且恒定的。因此,每个探险者对应一个可选的救援站区间。问题就变成了:有 m 个区间,n 个点,每个点最多被一个区间选择,求最多能满足多少个区间。这是一个经典的贪心问题:将所有区间按右端点升序排序,然后遍历区间,为每个区间贪心地分配其范围内最靠左的可用救援站。使用并查集可以高效地找到下一个可用的位置。------------------------------------题目三:题目大意:有 n (1 <= n, q <= 1e5) 个魔法水晶,能量为 ai (1 <= ai <= 1e5)。需要处理 q 次操作,操作分两种:1. 将第 i 个水晶的能量修改为 x;2. 查询区间 [l, r] 内所有水晶能量的波动度(方差)。方差定义为 (1/m) * sum((bi - mean)^2)。解法思路:直接计算方差涉及均值,不便于用数据结构维护。关键是对方差公式进行数学变换:Var(X) = E(X^2) - (E[X])^2。对于一个区间,这等价于`(区间平方和 / 区间长度) - (区间和 / 区间长度)^2`。这样,我们只需要维护区间的和与区间的平方和。这可以用两个树状数组(或线段树)来高效实现:一个树状数组维护 `sum(ai)`,另一个维护 `sum(ai^2)`。单点修改时,在这两个树状数组上都进行更新。区间查询时,分别查出区间和与区间平方和,再代入公式计算即可。具体的详细代码和题解可以戳我主页的文章查看
投递阿里巴巴集团等公司10个岗位
0 点赞 评论 收藏
分享
------------------------------------题目一:题目大意:给定 n (1 <= n <= 2e5) 张数字卡片,每张上有一个正整数 ai (1 <= ai <= 1e9, 不含0)。你需要将所有卡片上的数字拆分成独立的数位,然后将这些数位重新分配,组成 n 个新的数字,但每个新数字的位数必须与原来该位置的卡片上的数字位数相同。目标是让这 n 个新数字的总和最大。解法思路:这是一个贪心问题。要使总和最大,必须让越大的数位处在权重越高的位置上(例如,百位的权重大于十位)。因此,最优解法是:第一步,将所有数字拆分成单个的数位,放入一个列表。第二步,根据所有原始数字的位数,计算出所有位置的权重(如1, 10, 100等),放入另一个列表。第三步,将数位列表和权重列表都按降序排序。最后,将排序后的两个列表中的元素一一对应相乘再求和,即可得到最大的魔法能量值。------------------------------------题目二:题目大意:有一条含 n (1 <= n <= 1000) 颗珠宝的项链,每颗价值为 ai (1 <= ai <= 2e5)。对于每个数量 m (从1到n),你需要从项链的某个前缀中(比如前 i 颗)选出 m 颗珠宝(保持原始相对顺序),并计算成本。成本 = (i - m) * k + (所选m颗珠宝的总价值)。你需要对每个 m,找出其最小的设计成本。(T 组数据, 1 <= T <= 50)解法思路:这是一个动态规划问题。可以定义 `dp[i][j]` 为“选择 i 颗珠宝,且最后一颗是原项链中的第 j 颗时,所选珠宝的最小价值总和”。状态转移方程为:`dp[i][j] = a[j] + min(dp[i-1][p])` 其中 `p < j`。这个转移可以通过维护前缀最小值来优化。得到DP表后,对于每个 m,最终成本是 `min(dp[m][i] + k * (i - m))` for `i >= m`。由于 `dp[i]` 只依赖于 `dp[i-1]`,可以使用滚动数组将空间复杂度优化到 O(n)。------------------------------------题目三:题目大意:给定一个长度为 n (1 <= n <= 2e5) 的非严格递增序列,其中部分数字缺失,用 0 表示 (0 <= ai <= 1e9)。已知序列的第一个和最后一个数不为0。你需要计算有多少种方法填补这些0,使得整个序列仍然保持非严格递增,结果对 1e9 + 7 取模。解法思路:这是组合数学问题。序列中已有的非零数字将整个序列分割成若干个独立的待填补区间。对于任意一个由非零数 L 和 R 包围的区间,假设中间有 c 个0,我们需要在这 c 个位置填上数,使得 L <= a_i <= ... <= a_j <= R。这等价于从 [L, R] 这个范围内的 `R - L + 1` 个数中,可重复地选出 c 个数,方案数符合多重组合(隔板法)模型。公式为 C((R-L)+c, c)。由于 R-L 的值可能很大,需要用 `(N*(N-1)*...*(N-c+1)) / c!` 的形式计算组合数,并使用费马小定理求乘法逆元来处理除法。最终答案是所有独立区间方案数的乘积。具体的详细代码和题解可以戳我主页的文章查看
投递小红书等公司10个岗位
0 点赞 评论 收藏
分享
------------------------------------题目一:题目大意:有 n (1 <= n <= 10000) 名学生报名三个社团 A、B、C,每个社团有固定的人数上限。系统按学生提交报名表的时间顺序处理,并根据学生的志愿优先级(1-3个志愿)进行分配。如果第一志愿已满,则尝试第二志愿,以此类推。你需要统计最终每个社团的成员名单。解法思路:这是一道直接的模拟题,核心是遵循“先到先得”和“志愿优先”的规则。维护三个社团的剩余名额。按顺序读入每个学生的信息,然后遍历该学生的志愿列表。对于每个志愿,检查对应社团是否还有名额。如果有,则将该学生分配到该社团,减少一个名额,并立即停止处理该学生的后续志愿,转而处理下一个学生。如果所有志愿都尝试过但都已满员,则该学生无法加入任何社团。------------------------------------题目二:题目大意:有 n (1 <= n <= 3000) 个音乐团体,每个团体有 m (1 <= m <= 100) 名成员,每位成员都有一个演出水平评分。你需要从每个团体中各选一名成员,组成一个 n 人的超级乐队。目标是让这个乐队中水平最高与最低的成员差距最小。请求出这个最小的可能差距。解法思路:这个问题可以巧妙地转化为一个滑动窗口问题。首先,将所有 n*m 个成员的信息(评分、所属团体编号)存入一个列表,并按评分从低到高进行排序。然后,问题就变成了在这个排好序的列表中,寻找一个最短的区间,这个区间内包含了来自所有 n 个不同团体的成员。这可以用经典的双指针(滑动窗口)技巧来解决:用一个指针(right)向右扩展窗口,直到窗口内集齐了所有团体的成员;然后,移动左指针(left)来收缩窗口,直到不再满足条件。在每次收缩前,都计算当前窗口的差距(members[right].score - members[left].score)并更新全局最小值。------------------------------------题目三:题目大意:在一个 n x m (1 <= n, m <= 50) 的迷宫中,有 k (1 <= k <= 5) 件古董和一个起点 'S'。迷宫中还有墙'#'和路'.'。移动会消耗时间。一个特殊的规则是:当你已经收集了 a 件古董后,每移动一步,所有未被收集的古董都会损失 a 点价值(价值最低降至1)。你需要规划一个收集所有 k 件古董的顺序,使得最终得到的总价值最高。解法思路:此题的核心突破口在于 k 的值非常小 (k <= 5)。这意味着所有可能的收集顺序数量 k! (最多 5! = 120) 是完全可以接受枚举的。因此,解法分为两步:首先,通过广度优先搜索(BFS)预计算出所有关键点(起点和 k 个古董位置)之间的两两最短路径长度。然后,枚举所有 k! 种排列组合作为收集顺序。对于每一种顺序,模拟整个过程:从起点出发,按顺序访问古董,在每次移动时,根据已收集的古董数量和移动的步数,更新所有尚未收集的古董的价值,并累加最终收集到的价值。最后在所有顺序中取最大值。------------------------------------题目四:题目大意:在一个长度为 n (1 <= n <= 100) 的一维地面上,有 m (1 <= m <= 1000) 个彩球从不同高度、不同时间开始下落。你需要控制一个筐来接球。每秒可以向左或向右移动一格,或不动。接到普通球得分,但接到陷阱球(积分为0)会被“冰冻”在原地3秒。在冰冻期间仍可接球,但无法移动。如果冰冻期内又接到陷阱球,冰冻时间重置为3秒。目标是获得最高总积分。解法思路:这是一个在时间和空间上进行的动态规划问题。首先,可以确定每个球的落地时间(=初始高度y + 开始下落时间t)。DP的状态可以设计为 `dp[time][pos][freeze]`,表示在 `time` 时刻,位于 `pos` 位置,且冰冻状态为 `freeze`(剩余冰冻秒数)时能获得的最大积分。状态转移则按时间顺序进行:`dp[t+1][...][...]` 的值由 `dp[t][...][...]` 转移而来。如果当前状态不是冰冻的(`freeze == 0`),则可以从 `pos-1`, `pos`, `pos+1` 三个位置转移过来;如果是冰冻的(`freeze > 0`),则只能从 `pos` 位置转移过来。在每个新位置,检查该时刻是否有球落下,加上其积分,并根据是否为陷阱球更新新的冰冻状态。
投递网易等公司10个岗位
0 点赞 评论 收藏
分享
------------------------------------题目一:题目大意:有 n (1 <= n <= 50000) 名研究生和 m (1 <= m <= 100000) 套资料。每名研究生需要一个连续编号的资料区间 [Li, Ri]。你需要将所有资料分到两个阅览室,使得尽可能多的研究生获得认证。认证条件是:某研究生需要的资料区间 [Li, Ri] 能完全覆盖其中一个阅览室的所有资料。解法思路:关键在于简化问题。最优的分配方案之一,必然是让其中一个阅览室只存放一套资料,例如只放资料 p。在这种情况下,研究生只要其需求区间 [L, R] 包含了资料 p,就可以获得认证。因此,问题转化为:找到哪个资料编号被最多的区间所覆盖。这是一个经典的区间覆盖问题,可以使用差分数组解决。遍历所有研究生的需求区间 [L, R],在差分数组上执行 diff[L]++ 和 diff[R+1]--。最后,计算差分数组的前缀和,其过程中的最大值就是答案。------------------------------------题目二:题目大意:在一个 n x m (1 <= n, m <= 8) 的方形区域中,有一些位置被标记为“*”。你可以用 1x3 或 3x1 的石柱覆盖区域,但每个石柱的至少一端必须在“*”上,且石柱不能重叠。当无法再放置任何石柱时,形成一个最终布局。问总共可能有多少种不同的最终布局状态(只关心哪些格子被覆盖)。(标记位置不超过13个)解法思路:由于标记点数量和网格大小都非常有限,这道题可以通过状态搜索来解决。核心是为每个“*”标记点决策如何放置石柱(或不放置)。我们可以用深度优先搜索(DFS)来枚举所有可能的放置组合。为了高效地表示和检查网格的占用状态,可以使用位运算(bitmask),一个64位的整数即可表示整个8x8的网格。DFS的每一层对应一个标记点,尝试以该点为端点向四个方向放置石柱,如果放置不越界且不与当前已占用的格子重叠,就更新mask并递归到下一个标记点。所有搜索完成后,将最终的mask存入一个集合(Set)中,集合的大小即为不同布局状态的数量。
投递小米集团等公司10个岗位
0 点赞 评论 收藏
分享
------------------------------------题目一:题目大意:箱子上有 n (1 <= k <= n <= 5e4) 个按钮,每个按钮上的数字在 1 到 k 之间。你需要按顺序选择按钮,形成一个长度为 k 的子序列,要求这个子序列包含 1 到 k 每个数字各一次,并且是所有可能方案中字典序最小的。解法思路:这是一个经典的单调栈问题。核心是贪心思想,遍历数字序列,用一个栈来维护当前最优的子序列。当遇到一个新数字时,如果它比栈顶数字小,并且栈顶数字在后续序列中还会出现,那么就可以将栈顶数字弹出(相当于“反悔”),换入当前这个更小的数字,以获得更优的字典序。通过一个计数数组来记录每个数字的剩余出现次数,以判断是否可以安全地弹出栈顶。------------------------------------题目二:题目大意:给定一个长度为 n (1 <= n <= 100) 的01编码带,以及 m (1 <= m <= 6) 个需要验证的非负整数 (0 <= a_i < 1024)。你需要判断,这 m 个整数各自的二进制表示(不含前导零)能否在编码带中找到对应的、互不重叠的连续片段。(T 组数据, 1 <= T <= 20)解法思路:由于需要验证的数字数量 m 非常小,这指向了搜索算法。首先,预处理出每个数字的二进制字符串,并在编码带中找到它所有可能的匹配位置。然后,使用深度优先搜索(DFS)来为这 m 个数字分配匹配区间。搜索过程中,用一个布尔数组或位集记录编码带上已被占用的位置,确保新分配的区间不与之前的重叠。一个重要的优化是,优先为匹配位置选择最少的数字进行搜索,这样可以更快地剪枝,提高效率。
投递京东等公司10个岗位
0 点赞 评论 收藏
分享

创作者周榜

更多
关注他的用户也关注了:
牛客网
牛客网在线编程
牛客网题解
牛客企业服务