0813小红书秋招笔试复盘三道题

#牛客AI配图神器##秋招笔面试记录#

------------------------------------

题目一:

题目大意:
给定 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!` 的形式计算组合数,并使用费马小定理求乘法逆元来处理除法。最终答案是所有独立区间方案数的乘积。

具体的详细代码和题解可以戳我主页的文章查看
全部评论

相关推荐

中途加入只写了1,3,第二题没看懂要干啥第一题:优先队列&nbsp;+&nbsp;贪心可以想到贪心,先把所有的数给拆出来,比如[11,&nbsp;299],拆成[9,9,2,1,1],然后贪心,把大的数放在位数高的那个元素就行了,比如例子中可以变成[(1,2),&nbsp;(2,3)]表示第一个数有两位,第二个数有三位,然后放入优先队列,首先取出第二个元素,将第三位变成9,现在第二个元素只剩两位了,继续放入优先队列,按照该顺序写就OK。代码如下:#include&nbsp;&lt;bits/stdc++.h&gt;using&nbsp;namespace&nbsp;std;const&nbsp;int&nbsp;N&nbsp;=&nbsp;2e5&nbsp;+&nbsp;10;int&nbsp;a[N]&nbsp;,h[10];pair&lt;int,&nbsp;int&gt;&nbsp;b[N];int&nbsp;main()&nbsp;{int&nbsp;n;cin&nbsp;&gt;&gt;&nbsp;n;priority_queue&lt;pair&lt;int,&nbsp;int&gt;&gt;&nbsp;pq;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;n;&nbsp;i&nbsp;++)&nbsp;{cin&nbsp;&gt;&gt;&nbsp;a[i];b[i].second&nbsp;=&nbsp;i;while&nbsp;(a[i])&nbsp;{h[a[i]&nbsp;%&nbsp;10]&nbsp;++;a[i]&nbsp;/=&nbsp;10;b[i].first&nbsp;++;}pq.push(b[i]);}while(pq.size()&nbsp;&gt;&nbsp;0)&nbsp;{pair&lt;int,&nbsp;int&gt;&nbsp;t&nbsp;=&nbsp;pq.top();pq.pop();int&nbsp;num&nbsp;=&nbsp;0;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;9;&nbsp;i&nbsp;&gt;=&nbsp;0;&nbsp;i&nbsp;--)&nbsp;{if&nbsp;(h[i]&nbsp;!=&nbsp;0)&nbsp;{h[i]&nbsp;--;num&nbsp;=&nbsp;i;break;}}a[t.second]&nbsp;=&nbsp;a[t.second]&nbsp;*&nbsp;10&nbsp;+&nbsp;num;t.first--;if&nbsp;(t.first&nbsp;!=0)&nbsp;{pq.push(t);}}long&nbsp;long&nbsp;res&nbsp;=&nbsp;0;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;0;&nbsp;i&nbsp;&lt;&nbsp;n;&nbsp;i&nbsp;++)&nbsp;res&nbsp;+=&nbsp;a[i];cout&nbsp;&lt;&lt;&nbsp;res;}第三题:组合数首先要推公式,如果两个数a[i]和a[j]之间有n个0,设z&nbsp;=&nbsp;a[j]&nbsp;-&nbsp;a[i],&nbsp;有多少种可能的序列,设为f(z,&nbsp;n),C是组合数。当n&nbsp;=&nbsp;1&nbsp;时,记为f(z,&nbsp;1),很简单,该0可能是a[i]&nbsp;-&nbsp;a[j]之间的任何数,有z&nbsp;+&nbsp;1&nbsp;种可能,f(z,&nbsp;1)&nbsp;=&nbsp;z&nbsp;+&nbsp;1&nbsp;=&nbsp;C(z+1,&nbsp;1)。当n&nbsp;=&nbsp;2&nbsp;时,固定第一个0,如果第一个0为x,那么第二个0就和n&nbsp;=&nbsp;1&nbsp;时一样,此时枚举第一个0从[0-z],f(z,&nbsp;2)&nbsp;=&nbsp;f(z,1)&nbsp;+f(z-1,1)&nbsp;+&nbsp;...+f(1,&nbsp;1)&nbsp;+&nbsp;f(0,&nbsp;1)&nbsp;=&nbsp;1&nbsp;+...&nbsp;+z+1&nbsp;=&nbsp;C(z+2,&nbsp;2)。同理,&nbsp;n=3时,同理枚举第一个0。f(z,&nbsp;3)&nbsp;=&nbsp;f(z,&nbsp;2)&nbsp;+...&nbsp;f(0,&nbsp;2)&nbsp;=&nbsp;C(z+2,&nbsp;2)&nbsp;+&nbsp;C&nbsp;(z&nbsp;+&nbsp;1,&nbsp;2)&nbsp;+&nbsp;...&nbsp;C(2,&nbsp;2)&nbsp;=&nbsp;C(z+3,&nbsp;3)可以看出来f(z,&nbsp;n)&nbsp;=&nbsp;C(z&nbsp;+&nbsp;n,&nbsp;n)&nbsp;=&nbsp;(z&nbsp;+n)!/(n!&nbsp;&amp;&nbsp;z!);#include&nbsp;&lt;bits/stdc++.h&gt;using&nbsp;namespace&nbsp;std;#define&nbsp;int&nbsp;long&nbsp;longconst&nbsp;int&nbsp;p&nbsp;=&nbsp;1e9&nbsp;+&nbsp;7;const&nbsp;int&nbsp;N&nbsp;=&nbsp;6e5&nbsp;+&nbsp;10;int&nbsp;a[N];int&nbsp;mul[N],&nbsp;dmul[N];int&nbsp;qs(int&nbsp;a,&nbsp;int&nbsp;b)&nbsp;{int&nbsp;res&nbsp;=&nbsp;1;while&nbsp;(b)&nbsp;{if&nbsp;(b&amp;1)&nbsp;res&nbsp;=&nbsp;res&nbsp;*&nbsp;a&nbsp;%&nbsp;p;a&nbsp;=&nbsp;a&nbsp;*&nbsp;a&nbsp;%&nbsp;p;b&nbsp;&gt;&gt;=&nbsp;1;}return&nbsp;res;}int&nbsp;C(int&nbsp;n,&nbsp;int&nbsp;m)&nbsp;{int&nbsp;cc&nbsp;=&nbsp;1;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;n&nbsp;-&nbsp;m&nbsp;+&nbsp;1;&nbsp;i&nbsp;&lt;=&nbsp;n;&nbsp;i&nbsp;++)&nbsp;cc&nbsp;=&nbsp;cc&nbsp;*&nbsp;i&nbsp;%p;return&nbsp;cc&nbsp;*&nbsp;dmul[m]&nbsp;%&nbsp;p;}int&nbsp;lucas(int&nbsp;n,&nbsp;int&nbsp;m)&nbsp;{if&nbsp;(m&nbsp;==&nbsp;0)&nbsp;return&nbsp;0;int&nbsp;a&nbsp;=&nbsp;n&nbsp;%&nbsp;p,&nbsp;b&nbsp;=&nbsp;m&nbsp;%&nbsp;p;if&nbsp;(b&nbsp;&gt;&nbsp;a)&nbsp;return&nbsp;0;return&nbsp;C(a,&nbsp;b)&nbsp;*&nbsp;lucas(n/p,&nbsp;m&nbsp;/p)&nbsp;%&nbsp;p;}signed&nbsp;main()&nbsp;{int&nbsp;n;&nbsp;cin&nbsp;&gt;&gt;&nbsp;n;vector&lt;int&gt;&nbsp;v;int&nbsp;res&nbsp;=&nbsp;1;mul[0]&nbsp;=&nbsp;dmul[0]&nbsp;=&nbsp;1;for&nbsp;(int&nbsp;i&nbsp;=&nbsp;1&nbsp;;&nbsp;i&nbsp;&lt;&nbsp;N&nbsp;;&nbsp;i&nbsp;++)&nbsp;{mul[i]&nbsp;=&nbsp;mul[i&nbsp;-&nbsp;1]&nbsp;*&nbsp;i&nbsp;%&nbsp;p;dmul[i]&nbsp;=&nbsp;qs(mul[i],&nbsp;p&nbsp;-&nbsp;2);}for&nbsp;(int&nbsp;i&nbsp;=&nbsp;1&nbsp;;i&nbsp;&lt;=&nbsp;n;&nbsp;i&nbsp;++)&nbsp;cin&nbsp;&gt;&gt;&nbsp;a[i];for&nbsp;(int&nbsp;i&nbsp;=&nbsp;1&nbsp;;&nbsp;i&nbsp;&lt;&nbsp;n;&nbsp;)&nbsp;{if&nbsp;(a[i]&nbsp;==&nbsp;0)&nbsp;{int&nbsp;j&nbsp;=&nbsp;i;while&nbsp;(a[j]&nbsp;==&nbsp;0)&nbsp;j++;int&nbsp;d&nbsp;=&nbsp;a[j]&nbsp;-&nbsp;a[i&nbsp;-&nbsp;1];int&nbsp;z&nbsp;=&nbsp;j&nbsp;-&nbsp;i;res&nbsp;=&nbsp;res&nbsp;*&nbsp;C(z&nbsp;+&nbsp;d,&nbsp;z)&nbsp;%&nbsp;p;i&nbsp;=&nbsp;j;}&nbsp;else&nbsp;i++;}cout&nbsp;&lt;&lt;&nbsp;res&nbsp;&lt;&lt;&nbsp;'\n';}
投递小红书等公司10个岗位
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务