牛客IOI周赛23-普及组题解

小L的数列

https://ac.nowcoder.com/acm/problem/218035

A 小L的作文

题目:
小 L 写了一篇很烂的作文,烂到老师都不愿意给它扣分,只能给他加分,已知老师比较牛,所以他发现一个字符 x 就会加一分。问你小 L 最后可以得到多少分。

解题思路

遍历表示作文的字符串 s,遇到 x 字符就向答案中加一。

#include<iostream>
using namespace std;

int main(){
    char x;
    string s;
    cin >> x >> s;
    int ans = 0;
    for(char c : s){
        if(c==x) ++ans;
    }
    cout << ans << endl;
    return 0;
}

B 小L的多项式

题目:
一天,小 L 收到了一个多项式 ,现在他想求这个多项式的若干点值。
即,给定 ,需要你求 。由于结果可能很大,你需要输出结果对 998244353 取模的值。

解题思路

使用多项式计算的秦九韶算法,对于每个 ,时间复杂度为

#include<iostream>
#include<vector>
using namespace std;

const int MOD = 998244353;

long long f(long long x, vector<int>&a){
    int n = a.size();
    long long ans = a[n-1];
    for(int i=n-2; i>=0; --i){
        ans *= x;
        ans += a[i];
        ans %= MOD;
    }
    return ans;
}

int main(){
    int n, m;
    cin >> n;
    vector<int> a(n+1);
    long long sum = 0;
    for(int i=0; i<=n; ++i){
        cin >> a[i];
        sum += a[i];
    }
    cin >> m;
    vector<int> x(m);
    for(int i=0; i<m; ++i){
        cin >> x[i];
    }
    for(int i=0; i<m; ++i){
        if(x[i]==1){
            cout << sum << " ";
            continue;
        }
        cout << f(x[i],a) << " ";
    }
    return 0;
}

C 小L的编辑器

题目:
小 L 发明了一个文本编辑器。
该文本编辑器的运行方式大概是这样的:一开始文本为空,有一个光标在开头,每一次小 L 会输入一个字符,该字符就会被插入到光标的位置上,然后光标会随机地停留在该字符的左边或右边。
现在小 L 用这个文本编辑器打了一大段文字,但他却忘了保存了,他只记得他依次打了哪些字符和打完每个字符后光标停在了该字符的左边还是右边,请帮助他还原出最终文本的内容。

解题思路

使用链表保存最终文本的内容。
如果光标停留在当前字符的左边,则将下一个字符插入当前字符的左边,反之则插入右边。
最后从头到尾输出链表的字符。
因为链表的插入操作的时间复杂度是 ,所以最终时间复杂度为 表示文本的字符串个数。

#include<iostream>
using namespace std;

struct ListNode{
    char val;
    ListNode* next;
    ListNode():val('0'),next(nullptr){}
    ListNode(char ch):val(ch),next(nullptr){}
};

int main(){
    string s, t;
    cin >> s >> t;
    ListNode* head = new ListNode();
    ListNode* cur = new ListNode(s[0]);
    head->next = cur;
    ListNode* pre = head;
    for(int i=1; i<s.size(); ++i){
        ListNode* q = new ListNode(s[i]);
        if(t[i-1]=='L'){
            pre->next = q;
            q->next = cur;
            cur = q;
        }
        else{
            q->next = cur->next;
            cur->next = q;
            pre = cur;
            cur = q;
        }
    }
    cur = head->next;
    while(cur){
        cout << cur->val;
        cur = cur->next;
    }
    cout << endl;
    return 0;
}

D 小L的数列

题目:
小L喜欢数和数列。小L称这些数为优秀的。小L称一个序列为好的当且仅当:
1.对于任意的 ,满足
2.对于任意的 ,满足 。其中, 的最大公因数。
3.对于任意的 这个数是优秀的。
现在,小L想知道最长的能称为好的的序列的长度是多少,容易证明这个长度是有穷的。

解题思路

首先筛选出素数。

先对数列 a 进行排序,这样满足条件 1。

动态规划:
dp[i] 表示加入 a[i] 的 b 数列的最长长度。
状态转移公式:dp[i] = max(dp[i], dp[x]+1)。其中 gcd(a[i],a[x])>1,i>x。

遍历 a,分解出每个值的质因数。
mp 记录排序后的 a 数列中当前最后一个包含某个质因数在 a 中的索引。

#include<iostream>
#include<vector>
#include<unordered_map>
#include<algorithm>
#include<cstdio>
using namespace std;

const int N = 100005;
int vis[N];
vector<int> p;

void f(){
    for(long long i=2; i<N; ++i){
        if(!vis[i]){
            p.push_back(i);
            for(long long j=i*i; j<N; j+=i){
                vis[j] = 1;
            }
        }
    }
}

int main(){
    f();
    int T, n;
    scanf("%d", &T);

    while(T--){
        scanf("%d", &n);
        vector<int> a(n);
        for(int i=0; i<n; ++i){
            scanf("%d", &a[i]);
        }

        sort(a.begin(),a.end());

        vector<int> dp(n,1);
        unordered_map<int,int> mp;
        int ans = 1;
        for(int i=0; i<n; ++i){
            int val = a[i];
            for(int fact : p){
                if(val<=1) break;
                if(val%fact==0){
                    if(mp.count(fact)>0){
                        int x = mp[fact];
                        dp[i] = max(dp[i], dp[x]+1);
                    }
                    mp[fact] = i;

                    while(val%fact==0) val/=fact;
                }
            }
            ans = max(ans, dp[i]);
        }

        printf("%d\n", ans);
    }
    return 0;
}
全部评论

相关推荐

各位前辈好,先说声抱歉,可能又是一篇“求骂醒”的帖子,但我真的需要一个方向。我的情况比大多数人都糟糕:双非软件工程,大四,马上毕业了,0实习经历,0工作经验。秋招根本没参加,原因很傻——我一头扎进了一个自己觉得“挺有意思”的项目里,天真的以为把项目做好工作自然会找上门。现在春招也快结束了,我才如梦初醒,发现简历投出去基本石沉大海。我没有什么能拿出手的背景,唯一能说的就是这个从后端到前端全栈独立开发的电影推荐平台。我知道在各位前辈眼里这大概率就是个小玩具,但我确实是下了功夫去琢磨的,它不是什么网上扒的代码,下面这些是我自己琢磨并落地的东西:项目概况:Spring&nbsp;Boot&nbsp;+&nbsp;MyBatis-Plus&nbsp;+&nbsp;Redis&nbsp;+&nbsp;JWT&nbsp;+&nbsp;MySQL&nbsp;+&nbsp;Vue3(前端是AI辅助生成的)我自己觉得花了心思的几个点:1.&nbsp;推荐算法落地:没有照搬别人的推荐逻辑。我是基于用户多维行为数据(评分、收藏、浏览时长)去计算标签权重,然后用“评分×log(热度+1)”的公式做加权排序;冷启动场景用热门数据兜底。推荐结果用Redis的ZSet缓存,用户行为一变化就主动删缓存触发重算。2.&nbsp;缓存体系设计:不是那种“面试八股文背完就扔”的表面理解。我实际遇到了缓存穿透和击穿的问题,然后自己用空值缓存+逻辑过期去解决。热门电影定时预热、批量查询用multiGet减少IO次数,还封装了MyCacheUtils通用模板,让整个项目其他模块也能复用这套缓存逻辑。3.&nbsp;并发与一致性:用Redis的SET&nbsp;NX&nbsp;EX实现了收藏/点赞的分布式锁,key精确到“用户+操作对象”级别,不是粗粒度的一锁全锁。异常回滚时Redis和MySQL数据一致性问题也思考并落地了。验证码的原子性校验用了Lua脚本来保证。4.&nbsp;性能是真实数据:我用JMeter做了2000并发的压测,引入Redis缓存体系后,推荐接口平均响应从6466ms降到155ms,吞吐量翻了一倍,缓存命中率干到98%以上。这些数据不是编的,是我自己反复调优跑出来的。说实话,做完这些的时候,看着压测报告我是挺兴奋的,觉得“这也算出活儿了吧”。但现实是,0实习好像成了我简历上的原罪,很多公司直接筛选条件就把我过滤了。所以我想跪求各位前辈指点我几个问题,每一条我都认真看、认真执行:1.&nbsp;关于简历:0实习的应届生,还有资格谈“项目亮点”吗?我这项目,是不是在专业面试官眼里就是一个“低配版培训项目”?如果这个项目还有救,该怎么在简历上呈现,才能让HR或者面试官至少愿意给我一个电话面试?如果没有,一个0实习的应届生到底该在简历上写什么?2.&nbsp;关于面试:如何用项目细节证明“我虽然没实习但真的能干活”?我挺怕面试官看到我没有实习经历就直接失去兴趣。真到了面试那一步,我该怎么引导对话,用上面这些技术细节去对抗“没实习=没工程经验”的刻板印象?比如缓存那块,怎么从“我解决了击穿”讲出一个有技术判断力和工程思维的完整故事?3.&nbsp;关于求职策略:错过了黄金窗口期,现在该冲什么样的公司?大厂我肯定不奢望了。现在这个时间点,我应该去投那些小公司和外包吗?要不要把薪资预期降到最低先入行再说?对于0实习的应届生,什么样的公司是真的有机会让我进去学技术、积累经验的?4.&nbsp;关于未来:如果现在直接找不到工作,我该怎么办?这段时间我想好了,如果实在是找不到研发岗,我要不要去干测试或者运维先入行?还是找家小公司被压榨一年攒个经验?还是干脆先找个其他工作边干边学等下一轮秋招?我什么建议都能接受。我知道自己起步晚了,代价得自己扛。现在唯一能做的就是面对现实,然后找到一条最有可能逆袭的路。希望前辈们能给我指个方向,即使简单几句“没救了”或者“还能救,去做XXX”我都非常感激。
jiestart:这简历肯定没面试的,你得包装个实习再加一个agent项目才有希望
点赞 评论 收藏
分享
评论
点赞
收藏
分享

创作者周榜

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