42号哈希 level
获赞
15
粉丝
4
关注
0
看过 TA
119
上海交通大学
2026
C++
IP属地:上海
暂未填写个人简介
私信
关注
04-20 21:45
已编辑
上海交通大学 C++
第一题 k路字符串 优先级队列第二题 裸的拓扑排序,注意判断是否有环第三题 一开始直接写的最长上升子序列(严格),WA,于是推断山的高度必须是整数,于是对nums[i]-i求最长上升子序列(不严格)AC第四题 样例过,提交之后过0%样例,没看出来哪里错了,贴一下代码 #include using namespace std;int main() {    //数据范围来说,至少是需要n方或者更好的算法    //注意读题,首先不是严格大于,其次需要注意交换需要前提条件,即a[i] > x,这意味着交换过程中,x的数值是原来越大的,和x交换的值的门槛也是越来越大,隐含的条件就是如果小于x的数字没有有序,那么久没办法完成操作了    //手玩一下:    //81 324 218 413 324 x = 18 如果与i>=1的位置交换,剩下的18没人可以换走,直接不可行    //18 324 218 413 324 x = 81 同理,如果与i >= 2的位置交换,剩下的81没有可以换走,直接不可行    //18 81 218 413 324 x = 324 我们选择将413与324交换    //18 81 218 324 324     //再来领悟一下样例    //0 2 3 5 4 x = 1 当前发现后面有一个4在捣乱,我们要想办法把它调整下来,但是要调整,就说明当前x = 1需要换上去到某一个位置,也就只能是和2换,这一步是固定的    //0 1 3 5 4 x = 2 同样的,捣乱的4还没有解决,所以继续要调整,当前x = 2只能换在begin,故而    //0 1 2 5 4 x = 3 begin变成了5的下标    //0 1 2 3 4 x = 5 此时发现已经解决//再来领悟一下输出-1的样例    //11 9 x = 10 当前begin = 0 end = 1,但是注意到nums[end] < x,最终不可以被移动,所以已经寄了    //以上过程说明:对于小于x的内容,如果是已经有序地位于开头,那么就已经不可行了    //对于大于x的无序的内容,如果存在多个,比如10 20 30 40 6 4 x= 3,其中6和4都是乱序的,但似乎此时并不需要决定和其中的谁交换,只能从begin开始交换    //3 20 30 40 6 4 x = 10    //3 10 30 40 6 4 x = 20    //3 10 20 40 6 4 x = 30    //3 10 20 30 6 4 x = 40 爆炸    //至此大胆提出假设:先处理得到其中单增的区间    //0 2 3 5 4 x = 1    //其中比x小的部分已经确保落在该有的位置上了    //0 [2 3 5] [4] x = 1 那么我们会把{[2, 3, 5] x = 1}变化为{[1 2 3] x = 5},即相当于原来有序的空间中最大的没了,最小的变成原有x。花费是有序空间大小    //然后x变成了原有空间中最大的那个,然后继续这样扫描//再来手玩一下:    //4 5 6 7 8 9 10 3 x = 1     //{[4 5 6 7 8 9 10] x = 1}->{[1 4 5 6 7 8 9] x = 10} 由于次大的9还是大于无序的3,所以没办法    //总结思路:线性扫描,找到从开始到现在最长的有序集(其中小于x的部分不统计长度)int t;    cin>>t;    while(t--)    {        int n, x;        cin>>n>>x;        vector nums(n);        for (int i = 0; i < n; ++i) cin>>nums[i];        int begin = 0, end = 0, costBegin = -1;        int ans = 0;        bool flag = true;        while(begin < n)        {            //end begin costBegin x ans            while(end + 1 < n && nums[end + 1] >= nums[end])//扫描到end,并更新end            {                if (costBegin == -1 && nums[end] > x) costBegin = end;                ++end;            }            // cout<<"begin = "<<<", end = "<<<", costBegin = "<<<'\n';            //从begin 到 end 递增,且从costBegin开始大于x            if (end == n - 1) break;            if (begin != end)            {                if (nums[end + 1] < nums[end - 1]) {flag = false; break;}//没办法调整                ans += (end - costBegin + 1);                x = nums[end];                end = begin = end + 2;                costBegin = -1;            }            else            {                if (nums[end] > x && x <= nums[end + 1]) {++ans; x = nums[end]; end = begin = end + 2; costBegin = -1;}                else {flag = false; break;}            }        }        if (flag) cout<<<'\n';        else cout<<"-1\n";    }    return 0;}
投递拼多多集团-PDD等公司10个岗位
0 点赞 评论 收藏
分享
专门在牛客上记录让自己破防的笔试题跪求路过大佬教教第三题做法## 编程题### 第一题输入n,然后输入一个长度为n的字符串s,接下来对于s的每一个前缀,将其依次反转然后拼接在一起,得到新的字符串s'输入m,接下来m次查询,要求输出s'的第m个字符(保证1 <= m <= (n + 1) * n / 2)**数据范围** n,m在1e5 对于所在的块写了一个二分,花了10min过的debug过程:第一次写的时候注意到了(n + 1)*n溢出风险,所以用的long long,但是x一开始用int存的将x从int换为long long之后,20%->100%### 第二题输入T,接下来T组数据每组数据:输入n,然后输入n个数,组成数组a。定义:对于一个长度至少为3的子序列,称其为V图,当x_1>x2>x3>...>xj且xj<xj+1<xj+2<...<xk 输出当前数组所有V图中,极差最大的那个的极差。**数据范围** T在1e3, n在1e5考虑每一个小标为j时对于答案的贡献,统计其左边和右边最大的数字,如果都大于a[j],则统计当前对答案的贡献左边右边最大的数字用dp,两边线性扫描。花了15分钟过的### 第三题输入n以及正整数集合S = {s1, s2, ..., sn} 输入m,之后m次询问,每次一个x。判断S中有无这样的一个子集T,s.t.对于任意在[1, x]范围的正整数y,都存在T的一个子集T',使得T'的元素之和等于y。如果存在,则输出所有满足上述条件的T中,元素个数最少的那一个;如果不存在,则输出-1。**数据范围** n,m小于1e5,x小于1e9。**样例** S = {1, 2, 4, 8, 16} 查询 7 8 32的期望结果分别为3 4 -1**当时做出的解题尝试以及思路回忆**:拿到题目觉得莫名像是最小线性筛,但是玩了一下样例之后发现不是这样的。没思路,先考虑简单一点的问题,“对于给定的子集T,验证其是否能覆盖1到x的所有数字”想法:对于T排序之后直接dp即可,不过x的范围是1e9,dp存不下,所以自顶向下记忆化搜索。好,思维没闲着,不过对于上面这个,子集T有2^2种可能,无法枚举,那如何做呢?基于上面做法,我们试试看贪心。对于查询x,每次选择S中≤x且最接近(x+1)/2的数num,将问题递归转化为解决1...max(num-1, x-num)。实现的话使用multiset和lower_bound进行二分查找,如果两边差值一样,优先使用较大的数字,否则选更靠近的那个#牛客AI配图神器#想了半天想到这个之后开始实现,实现完之后发现过不了样例,即 反例:S={1,2,4,8,32}, x=8时:我的贪心则会x=8第一次贪心选4,此时x=4;第二次贪2,此时x=2;第三次贪1,此时x=1。x大于0就会继续进while循环体,此时multiset找lowerbound的时候,较大的那一端选到的数字是8,大于x不予考虑,较小那一段没得数字了。即较大较小两端都没有可以选的数字了,break出while并输出-1无法继续选择导致失败,但正确解应为8,4,2,1**赛后反思**首先,其实可以写一个枚举然后验证的,这样如果有n < 30的数据点,至少可以拿一些部分分然后反思了我的贪心,应该自底向上贪心,初始cur=0,然后把S的所有元素全部插入到某一个数据结构中,由于选一个≤ cur+1的num可以让cur = cur + num,所以我们就贪心选数据结构中所有≤ cur+1元素中最大的那一个,更新cur,cnt,并从数据结构中删除被选择的数。如果cur大于等于查询x,返回cnr。如果数据结构中已经没有≤ cur+1的数可以选就break输出-1数据结构选择multiset的时候,时间复杂度为mnlogn,还是超时,不过正确性来说,应该是对的,可以大概想象到贪心正确性证明长啥样。TODO 正确性证明;考虑使用什么算法可以不超时。
投递淘天集团等公司10个岗位
0 点赞 评论 收藏
分享
第一次在牛客上发帖子,直接把写的笔试复盘md文件贴过来了。p.s. 暑期实习投递的太晚,只能说希望能有结果吧,没有的话后面找找日常实习也行,现在切忌不要过度焦虑,把战线拉长,每天好好沉淀总会有好结果的。# 题目回忆考试时长90分钟,其中10道选择题(总分30分),3道编程题(总分70分)## 选择题前五道题目考的很杂,涉及到数据结构(平衡二叉查找树、栈),磁盘计算等等后面的题目主要是围绕ML和LLM展开的,lr调整策略(余弦退火等)一题,ViT一题,微调好像考了三题## 编程题### 第一题q次查询,每次查询:n, m, w2, w3初始数字是n,每次操作可以(1)将当前乘以二,花费w2代价(2)将其乘以三,花费w3代价对于每次查询,输出从n开始,让其最终大于等于m的最小代价数据范围:- n, m <= 1e9- q <= 1e5### 第二题定义漂亮数:对于数字x,如果存在质数p,使得x % p == 0且p * p >= x,则x是一个漂亮数输入一个数字n,需要输出[1, n]范围内漂亮数的个数**数据范围**- n <= 5e5### 第三题输入n,m接下来n-1行,每行u,v,d表示树上u和v之间有一条长度为d的边然后m行询问,每行x,y,要求输出树上经过x和y两个点的简单路径的最大长度(其中简单路径是指路径上所有点互不相同)**数据范围**数据范围n和q都是5e5# 考场表现回忆以及反思## 选择题刚开考的时候明显没有进入状态,没有时间的紧迫感。有一道关于栈的题目描述相当奇怪,自我感觉读题的时候不专注。用时大约15分钟## 编程题### 第一题**解题心路过程**1. 一眼看上去是dp2. 但是数据范围是1e9,dp存不下,那看样子不是dp3. 考虑是不是一个数学问题可以直接求,比如是不是最佳策略只会是全乘二或者全乘三或者全乘三但是最后一次乘二4. 发现完全把握不住,于是还是考虑dp,存不下那我们就记忆化搜索具体时间不记得了,但是我记得这个题目和第二题加起来是花了30分钟不到### 第二题**解题心路过程**1. 拿到题目首先转化条件,一个数是漂亮数当且仅当他的最大质因数的平方大于等于这个数(n >= 2时),特别的,1不是漂亮数2. 这个时候有冲动直接暴力检验每一个数是不是漂亮数,但是这样是O(n * sqrt(n)),太慢了,决定再想想,想不出来就先写暴力3. 印象中这个时候直接跳过去看了一下第三题,题干没仔细看完,又跳回来做第二题4. 突然灵光一闪,逆向思维一下,对于每一个质数p,找到以其为最大质因数的所有漂亮数即可。类似于n = 10时。p = 2 -> 2 * 1, 2 * 2; p = 3 -> 3 * 1, 3 * 2, 3 * 3; p = 5 -> 5 * 1, 5 * 2 ... 直到p大于n**代码实现过程**实现的话就是质数筛,然后对于每一个p,统计其对于答案的贡献但是一开始写的是 res += n / p,发现过不了样例之后加了几条调试信息,于是改成了res += min(n / p, p),这个调试过程大概花费了5分钟### 第三题**解题心路过程**1. 对于题干还不太理解,于是手玩了一下样例2. 很快意识到这是一个lca + 树上dp,思考了一下处理查询所需要的信息:首先对于每一个点,维护它往下的路径最大值(这个直接一个dfs就行,树上dp),然后对于查询的两个点,以他们为端点的路径就是一个lca + 树上前缀和3. 注意这里并没有去思考上面这个是不是有逻辑bug,直接就开始编码了**代码实现过程**整体编码过程并不利索,我有点分不清是我自己本身编码熟练度不够,还是考试的时候太放松没有紧迫感依稀记得 当时看到时间还有30多分钟,感觉编码的时候有点悠哉游哉的,等实现完dfs,得到parent[][0], maxDis[], preSum[], dep[]之后进一步得到parent[][]可以确信的是,关于lca的部分我写的很谨慎,都是在脑子里把过程想清楚了再编码,这一点倒是正确的最后实现完毕之后,只剩下几分钟,跑了测试样例,WA于是加输出调试,发现自己读进来的x和y在找lca的时候直接修改了x,y。后续查询的时候又是直接用的x,y。赶紧修复了这个,找lca的时候修改的是x,y的副本的值样例过了,但是提交之后通过样例0%,这个时候时间好像只有3分钟了,突然意识到一个逻辑bug,当x是y的祖先关系的时候,maxDis[x] + maxDis[y] + (preSum[x] + preSum[y] - 2 * preSum[lca])中,两个maxDis有可能出问题,即y在x往下延申最大路径上但是我如何知道在不在?在困惑中考试结束了**赛后正解思考**记一个第二深的叶子再最深和第二深记一下具体是哪个叶子这样可以判断v是不是在u最深的叶子那条路上如果是就用第二深的# 一些反思TODO
查看7道真题和解析 投递美团等公司10个岗位
0 点赞 评论 收藏
分享

创作者周榜

更多
关注他的用户也关注了:
牛客网
牛客企业服务