【LittleXi】拼多多后端8.11解题报告

极限ak,开题顺序3421成谜

A、旅行计划

题意:

给定n个旅行计划,每个旅行计划完成的时间只能是xi,xi+d,xi+2d,...,并且每天最多只能完成一个旅游,求最小时间

题解:

可以考虑维护当前的天数result

如果result小于当前旅行计划开始的天数,那么result = day_i

否则求最小的b使得day_i + b * d > result

注意坑就是求b的时候,也可以day_i + b * d = result , 此时要b++

// 1
#include<bits/stdc++.h>
using namespace std;
#define ll long long

void solve(){
    ll n;
    cin>>n;
    vector<vector<ll>> data(n,vector<ll>(3));
    for(ll i= 0;i<n;i++){
        cin>>data[i][0]>>data[i][1]>>data[i][2];
    }
    sort(data.begin(),data.end());
    ll result = 1;
    for(ll i =0;i<n;i++){
        vector<ll> current = data[i];
        if(result < current[1]){
            result = current[1];
        }
        else{
            ll day = current[1];
            ll dis = result - day;
            ll b = dis/current[2] + (dis%current[2] > 0);
            if(day + b * current[2]==result) b ++;
            result = day + b * current[2];
        }
    }
    cout<<result<<endl;
}

signed main(){
    cin.tie(0);cout.tie(0);
    ios::sync_with_stdio(0);
    solve();
}


B、多多的作业

题意:

给定n个作业,作业有开始时间和需要的时间,求最小总作业消耗时间,单个作业消耗时间是作业完成时间减去作业开始时间

题解:

可以考虑使用优先队列进行贪心, 每次获取作业的时候,对于前面那个时间片,我们优先让消耗时间小的作业被计算

代码:

// 2
#include<bits/stdc++.h>
using namespace std;
#define ll long long

void solve(){
    ll n;
    cin>>n;
    vector<pair<ll,ll>> vp(n);
    for(ll i =0;i<n;i++) cin>>vp[i].first>>vp[i].second;
    priority_queue<ll,vector<ll>,greater<ll>> pq;
    ll t = 1 , ans = 0;
    pq.push(vp[0].second);
    for(ll i =1;i<n;i++){
        ll d = vp[i].first - vp[i-1].first;
        while(pq.size()&&d){
            auto x = pq.top();pq.pop();
            ll dis = min(x,d);
            ans += dis * (pq.size() + 1);
            x -= dis ; d -= dis;
            if(x) pq.push(x);
        }
        pq.push(vp[i].second);
    }
    while(pq.size()){
        ll x = pq.top();pq.pop();
        ans += x * (pq.size() + 1);
    }
    cout<<ans;
}

signed main(){
    cin.tie(0);cout.tie(0);
    ios::sync_with_stdio(0);
    solve();
}

C、玫瑰和牡丹

题意:

给一个01串,你可以最多选择一个区间进行反转,0->1 , 1->0 ,求最终abs(cnt[0]-cnt[1])的可能数

题解:

我们可以这样考虑,每次延长我们的[l,r]区间一次,cnt[0] - cnt[1] 要么+1,要么-1,所以我们可以求一个区间,使得cnt[0] - cnt[1] 最大或者最小,这个可以使用前缀和解决,那么对于最大的cnt[0] - cnt[1] , 一定可以每次+2到达,所以沿途的数字都可以到达

代码:

// 3
#include<bits/stdc++.h>
using namespace std;
#define ll long long
void solve(){
    int n ;cin>>n;
    vector<int> a(n);
    for(int&x:a) cin>>x;
    for(int&x:a) if(x==0) x = -1;
    int prmi = 0 , prmx = 0;
    int pr = 0;
    int mx = 0 , mi = 0;
    for(int i = 0;i<n;i++){
        pr += a[i];
        mx = max(mx,pr-prmi);
        mi = min(mi,pr-prmx);
        prmx = max(prmx,pr);
        prmi = min(prmi,pr);
    }
    set<int> se;
    int sm = accumulate(a.begin(),a.end(),0);
    for(int i = sm - 2*mx ; i <= sm -2*mi;i+=2){
        se.insert(abs(i));
    }
    cout<<se.size();
}

signed main(){
    cin.tie(0);cout.tie(0);
    ios::sync_with_stdio(0);
    solve();
}


D、哈希表

难度:区域赛铜牌题目,一股ACM味儿

题意:

哈希函数为f = x % n , 给定一个插入完成的哈希表,要求还原插入顺序,如果多个可能,还原字典序最小的

题解:

很容易想到使用拓扑排序,对于从i位置跳到j位置的数字, 将[i,j-1]的所有点连向j,然后进行拓扑排序+贪心就行,时间复杂度n^2 , 不行

可以考虑优化,删除一个数字之后,一定是右边最靠近这个数字可能被选,可以压进优先队列中,查找右边那个数字可以考虑使用树状数组+二分,时间复杂度nlg^2n

代码:

// 4
#include<bits/stdc++.h>
using namespace std;
#define ll long long
//坐标从0开始直接用的树状数组
template <typename T>
class Fenwick
{
private:
    int n;
    vector<T> c;
    int lowbits(int x){
        return (-x) & x;
    }
    int pre_sum(int i){
        int re = 0;
        for (; i > 0; i -= lowbits(i))
            re += c[i];
        return re;
    }
public:
    explicit Fenwick<T>(vector<T> v){
        this->n = v.size();
        this->c = vector<T>(n+1,0);
        for(int i=0;i<n;i++)
            add(i,v[i]);
    };
    void add(int i, int val){
        ++i;
        for (;i<=n; i += lowbits(i))
            c[i] += val;
    }
    int range_sum(int i,int j){
        ++i;++j;
        return pre_sum(j) - pre_sum(i - 1);
    }
};


void solve(){
    int n;cin>>n;
    vector<int> a(n);
    for(int &x:a) cin>>x;
    priority_queue<pair<int,int>,vector<pair<int,int>>,greater<pair<int,int>>> pq;
    map<int,int> mp;
    for(int i =0;i<n;i++){
        if(a[i]==-1) a[i] = 0;
        else if(a[i]%n==i){
            pq.push({a[i],i});
            mp[a[i]] = 1;
        }
    }
    for(int i =0 ;i < n;i++) a.push_back(a[i]);

    vector<int> b = a;
    for(int&x:b) if(x) x = 1;
    Fenwick<int> fw(b);

    vector<int> ans;
    while(pq.size()){
        auto p = pq.top();pq.pop();
        int x = p.first , pos = p.second;
        ans.push_back(x);
        fw.add(pos,-1);fw.add(pos+n,-1);
        int l = pos , r = 2*n;
        while(l+1!=r){
            int m = l+r>>1;
            if(fw.range_sum(pos,m)==0) l = m;
            else r = m;
        }
        l++;
        if(l<2*n&&fw.range_sum(pos,l)==1){
            if(mp[a[l]]) continue; 
            int lp = a[l]%n;
            if(lp > l) l+=n;
            if(fw.range_sum(lp, l - 1)==0){
                mp[a[l]] = 1;
                if(l >= n ) l -= n;
                pq.push({a[l],l});
            }
        }
    }
    for(int x:ans) cout<<x<<" ";
}

signed main(){
    cin.tie(0);cout.tie(0);
    ios::sync_with_stdio(0);
    solve();
}

❤关注LittleXi ,谢谢喵, ACM金牌,持续更新更多题解❤

也可以提供大厂算法辅导喵

全部评论
第二题不需要给vp先排序吗?我记得测试用例并不是按照开始时间从小到大的啊。
1 回复 分享
发布于 2024-08-12 11:37 北京
最后一题没想清楚就觉得可以常数个点做前序节点,最后自己把自己卡了,浪费一个多小时,倒数十分钟切暴力 80。😭 现在想想,最后一题只需要针对后面第一个点的话,其实可以用并查集做到总复杂度O(N)。每次删除后向右指向未删的点,配合路径压缩就ok了。 这个思路过于简单,实现起来也特别短,还是太菜了...
1 回复 分享
发布于 2024-08-12 00:44 广东
是acm模式吗
点赞 回复 分享
发布于 2024-08-12 12:00 北京
佬太强了
点赞 回复 分享
发布于 2024-08-11 22:14 浙江
希佬😍
点赞 回复 分享
发布于 2024-08-11 22:04 湖南
100 100 100 0最后一题没时间了,75能进面试吗😭
点赞 回复 分享
发布于 2024-08-11 22:02 陕西

相关推荐

头像
04-27 15:11
已编辑
华东师范大学 算法工程师
暑期实习从2月开始投,面了两个月,流程该挂的都挂完了,腾讯字节一共号称是1.7w个hc,不知道都发给谁了,估计今年秋招要难顶。Timeline米哈游、美团、蚂蚁、微软等公司直接简历挂穿,没进面。携程:3.3&nbsp;投递、测评3.12&nbsp;笔试3.18&nbsp;一面3.25&nbsp;二面4.13&nbsp;ai面(hr面)4.14&nbsp;英语测评4.23&nbsp;offer(已拒)腾讯:2.6&nbsp;测评2.28&nbsp;wxg一面3.5&nbsp;wxg二面(挂)3.11&nbsp;teg一面3.21&nbsp;teg二面(取消)3.31&nbsp;teg一面4.10&nbsp;teg二面(挂)4.21&nbsp;wxg一面4.24&nbsp;wxg二面(挂)字节:1.28&nbsp;aml约面(取消)3.17&nbsp;火山一面(挂)4.8&nbsp;aml一面(挂)4.20&nbsp;抖音data一面(挂)阿里:3.23&nbsp;投递、测评3.28&nbsp;笔试3.31&nbsp;淘天一面4.8&nbsp;钉钉一面4.9&nbsp;淘天二面4.10&nbsp;阿里控股一面4.12&nbsp;钉钉二面(取消)4.15&nbsp;淘天hr面4.16&nbsp;淘天offer(已接)4.21&nbsp;高德一面(取消)4.22&nbsp;淘宝闪购一面(取消)面试最大的感触是,现在撞上ai转型,一堆老业务急着转向,新业务非常不成熟,研究型的组bar非常高根本进不去,业务侧挂着算法的岗位干的都是工程活,面试却又要问算法,另外agent的落地也远没有那么广,绝大多数还是那套写死的系统调一下llm&nbsp;api或者做做rag,其余少部分真的在搭agent的,基本不能在线上服务用什么很智能的模型,现阶段成本太高,进去大概率就是给垃圾模型从工程方面兜底,除了业务场景的应用和数据经验以外,技术方面很难有什么提升。算法岗做不了基模的还是去搜广推好,之前判断失误了完全没投,秋招不知道还进不进得去。
嵌入式的小白:不错啊,淘天也是挺好的,恭喜
我的求职进度条
点赞 评论 收藏
分享
评论
15
52
分享

创作者周榜

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