拼多多20220903笔试题解【部分】




1.字符串转换,每次可将字符串中的一种字母减一,求不超过k次的字典序最小的装换
2.左右横跳,求每个下标跳出去的步数
3.将#变为字母,求S和T最大覆盖的情况,如果有多个S,求字典序最小的答案
4.分班考试期望得分

1.要字典序最小,那么就从头往尾计算,记录每种字符可以转换到的最小字符,注意,一开始要先统计不超过k次所能计算到的最长部分,比如ekyv,发现ek都可以变到a,于是先考虑ek,次数先减去ek中的最大变换值,再对后面的字符串进行处理

#include <bits/stdc++.h>
using namespace std;


int main() {

    int T;
    cin >> T;
    while(T--) {
        int n, k;
        cin >> n >> k;
        string s;
        cin >> s;
        unordered_map<char, char>mp;
        for(char c = 'a'; c <= 'z'; c++) mp[c] = c;
        int index = 0;
        int max_ = 0;
        for(int i = 0; i < n; i++) {
            if(s[i] - 'a' <= k) {
                index++;
                max_ = max(max_, s[i] - 'a');//记录前面能减的那一部分,比如ekyv中的ek部分,最大是k
            }
            else break;
        }
        k -= max_;
        for(int i = 0; i < index; i++) {
            for(char c = 'a'; c <= s[i]; c++) mp[c] = 'a';
        }
        for(int i = index; i < n && k > 0; i++) {
            s[i] = mp[s[i]];
            int x = s[i] - 'a';
            x = min(x, k);
            k -= x;
            for(int j = 0; j < x; j++) {
                char c = s[i] - j;
                mp[c] = (char)(s[i] - x);
            }
        }
        for(int i = 0; i < n; i++) {
            s[i] = mp[s[i]];
        }
        cout << s << endl;
    }

    return 0;

}

2.其实就是一个图,判断是否有环就好了

#include <bits/stdc++.h>
using namespace std;


int main() {

    int T;
    cin >> T;
    while(T--) {
        int n;
        cin >> n;
        vector<char>s(n);
        vector<long long>a(n);
        for(int i = 0; i < n; i++) {
            cin >> s[i] >> a[i];
        }
        vector<long long>ans(n);
        for(int i = 0; i < n; i++) {
            if(ans[i] != 0) continue;
            vector<int>path;
            unordered_map<int, bool>vis;//是否走过该点,判断是否成环
            int now = i;
            long long step = 0;
            while(true) {
                // cout << "now: " << now << endl;
                step++;
                path.push_back(now);
                vis[now] = true;
                if(s[now] == 'L') now -= a[now];
                else now += a[now];
                if(now < 0 || now >= n) break;
                if(vis[now]) {
                    step = -1;
                    break;
                }
                if(ans[now] != 0) {
                    if(ans[now] == -1) step = -1;
                    else step += ans[now];//这个点有答案,直接加上
                    break;
                }
            }
            for(int j = 0; j < path.size(); j++) {
                // cout << path[j] << endl;
                if(step == -1) ans[path[j]] = -1;
                else ans[path[j]] = step - j;
            }
        }
        for(int i = 0; i < n; i++) {
            if(i < n - 1) cout << ans[i] << ' ';
            else cout << ans[i] << endl;
        }
    }

    return 0;

}

3.每两个字符可以交换,其实也就是问S中的字符能组成多少个T,计数就好了,注意要字典序最大,因此,如果还有剩的#就填入z,最后对可以填入的字符排序,就能保证字典序最大了

#include <bits/stdc++.h>
using namespace std;


int main() {

    string s, t;
    cin >> s >> t;
    int n = s.size();
    if(s.size() < t.size()) {
        int index = 1;
        while(true) {//调试用的,最后没错,说明后台数据里没有s小于t的情况
            index = index + 23;
        }
        cout << s << endl;
        return 0;
    }
    vector<int>count1(26);
    vector<int>count2(26);
    int count3 = 0;
    for(int i = 0; i < s.size(); i++) {
        if(s[i] != '#') count1[s[i] - 'a']++;
        else count3++;
    }
    for(int i = 0; i < t.size(); i++) {
        count2[t[i] - 'a']++;
    }


    int num = 0;//先看看s可以组成多少个完整的T,并减去这么多个T
    for(int i = 0; i < 26; i++) {
        if(count2[i]) num = min(count1[i] / count2[i], num);
    }
    for(int i = 0; i < 26; i++) {
        count1[i] -= num * count2[i];
    }
    string ans;

    while(count3 > 0) {
        bool flag = true;
        int temp_count3 = count3;
        vector<int>need(26);
        for(int i = 0; i < 26; i++) {
            if(count1[i] >= count2[i]) {//该字符可以由s组成
                count1[i] -= count2[i];
            } else if(count3 >= count2[i] - count1[i]) {//s不够了,由#来凑
                count3 -= count2[i] - count1[i];
                need[i] = count2[i] - count1[i];
                count1[i] = 0;//这里忘记减了,卡了好久。。
            } else {
                flag = false;
            }
        }
        if(!flag) {
            count3 = temp_count3;
            break;
        }
        for(int i = 0; i < 26; i++) {
            while(need[i]--) {
                ans.push_back((char)(i + 'a'));
            }
        }
    }
    while(count3--) {
        ans.push_back('z');
    }
    sort(ans.begin(), ans.end());
    int index = ans.size() - 1;
    for(int i = 0; i < n; i++) {
        if(s[i] == '#') {
            s[i] = ans[index--];
        }
    }
    
    cout << s << endl;


    return 0;

}

4.第三题忘记减了,卡了好久,第四题就处理了下数据,求思路


#笔试##拼多多##拼多多笔试##秋招#
全部评论
第一题思路一样,样例也过了,结果0%。。。
1 回复 分享
发布于 2022-09-03 17:34 北京
问下楼主之前用的什么内推方式?感谢呢
点赞 回复 分享
发布于 2022-09-03 17:47 江苏
T4就是分层求平均值,然后r在的那层和最后一层特殊处理一下。我是先做了124,T3最后没写完qaq
点赞 回复 分享
发布于 2022-09-03 17:57 北京
牛皮
点赞 回复 分享
发布于 2022-09-03 23:09 陕西
楼主三道都a了吗
点赞 回复 分享
发布于 2022-09-04 15:05 广东
拼多多不是只有非技术岗开了吗
点赞 回复 分享
发布于 2022-09-05 15:02 湖北
hi~同学,秋招遇“寒气”,牛客送温暖啦!23届秋招笔面经有奖征集中,参与就得牛客会员7天免费体验,最高赢300元京东卡!戳我去看>>>https://www.nowcoder.com/link/zhengjipinglun
点赞 回复 分享
发布于 2022-09-05 15:02 北京

相关推荐

10-09 22:05
666 C++
找到工作就狠狠玩CSGO:报联合国演讲,报电子烟设计与制造
点赞 评论 收藏
分享
评论
3
17
分享
牛客网
牛客企业服务