字节2020笔试题总结

第一题:
图片说明
这种字符串模式匹配的题经常采用有限状态机的方法,差一点的方法是双指针,一般会更加麻烦,要熟悉状态机的使用。
我的代码:

#include<string>
#include<vector>
#include<iostream>
using namespace std;
int main() {
    int n = 0;
    cin>>n;
    while (n--) {
        string s;
        cin>>s;
        char cur = s[0];
        string res = "";
        res += cur;
        int state = 0;
        for (int i = 1; i < s.size(); i++) {
            if (state == 0) {
                res += s[i];
                if (s[i] == cur) state = 1;
                else {
                    cur = s[i];
                    continue;
                }
            }
            else if (state == 1) {
                if (s[i] == cur) continue;
                else {
                    state = 2;
                    res += s[i];
                    cur = s[i];
                }
            }
            else if (state == 2) {
                if (cur == s[i]) continue;
                else {
                    state = 0;
                    cur = s[i];
                    res += s[i];
                }
            }
        }
        cout<<res<<endl;
    }

    return 0;
}

第二题:
图片说明
这道题可以利用双指针来做,第一个指针指向A特工的位置,第二个指针去找A特工在该位置下另外两名特工的最远位置,利用组合数求解总次数后取模即可。

#include<string>
#include<vector>
#include<iostream>
using namespace std;
int main() {
    long long n = 0, dis = 0;
    cin>>n;
    cin>>dis;
    long long left = 0;
    long long right = 0;
    vector<int> buildings(n);
    long long res = 0;
    for (long i = 0; i < n; i++) cin >> buildings[i];
    while (left < n - 2) {
        if (right < n && buildings[right] - buildings[left] <= dis) right ++;
        else {
            res += (right - left - 1)*(right - left - 2)/2;
            left ++;
        }
    }
    cout<<res%99997867;
    return 0;
    }

第三题:
图片说明
这种游戏一般由于数据规模较小,可以利用回溯来暴力穷举可能,关键点在于每次都先加入第14张牌,然后再判断是否可行。

#include<string>
#include<vector>
#include<iostream>
using namespace std;
void dfs(vector<int>& result, unordered_map<int, int>& fly, unordered_map<int, int>& rest, int pos) {
    if (pos == 12) {

        return;
    }
    for (int i = 1; i <= 9; i++) {
        if (fly[i] >= 2) {
            fly[i] -= 2;
            dfs(result, fly, pos + 2);
            fly[i] += 2;
        }
        if (i <= 7 && fly[i] && fly[i+1] && fly[i+2]) {
            fly[i] --;
            fly[i+1] --;
            fly[i+2] --;
            dfs(result, fly, pos + 3);
            fly[i] ++;
            fly[i+1] ++;
            fly[i+2] ++;
        }
    }
}
int main() {
    unordered_map<int, int> fly;
    for (int i = 1; i <= 13; i ++) {
        int tmp = 0;
        cin>>tmp;
        fly[tmp] ++;
    }
    unordered_map<int, int> rest;
    for (int i = 1; i <= 9; i++) {
        rest[i] = 4 - fly[i];
    }
    vector<int> result;
    dfs(1)
    return 0;
    }

第四题:
图片说明

这道题可以采用的数据结构包括哈希表和map。
利用哈希表无法处理pair,因此题解采用了map,代码如下:

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

int main()
{
    int n, m;
    cin >> n;

    int len;
    pair<int, int> xy;

    while (n--)
    {
        cin >> m;

        int maxCnt = 0;
        map<pair<int, int>, int> preFeaTimes;
        map<pair<int, int>, int> feaTimes;
        while (m--)
        {
            cin >> len;
            for (int i = 0; i < len; i++)
            {
                cin >> xy.first >> xy.second;

                if (preFeaTimes.count(xy))
                    feaTimes[xy] = preFeaTimes[xy] + 1;
                else
                    feaTimes[xy] = 1;

                if (feaTimes[xy] > maxCnt)
                    maxCnt = feaTimes[xy];
            }
            preFeaTimes.clear();
            preFeaTimes.swap(feaTimes);
        }
        cout << maxCnt << endl;
    }

    return 0;
}

我的方法如下:

#include<iostream>
#include<unordered_map>
#include<vector>

using namespace std;
int check(vector<int>& seq) {//0 1 2 6 7 
    int tmp = -1;
    for (int i = 0; i < seq.size(); ) {
        int cur = i;
        while (cur < seq.size() - 1 && seq[cur + 1] - seq[cur] == 1) cur ++;
        tmp = max(tmp, cur - i + 1);
        if (i == cur) i ++;
        else i = cur;
    }
    return tmp;
}
int main() {
    int loop = 0;
    cin >> loop;
    while (loop --) {
        int frame = 0;
        cin >> frame;
        unordered_map<int, unordered_map<int, vector<int> > > map;
        for (int i = 0; i < frame; i++) {
            int sz = 0;
            cin >> sz;
            while (sz --) {
                int a, b;
                cin >> a;
                cin >> b;
                map[a][b].push_back(i);
            }
        }
        int resVal = -1;
        for (auto m:map) {
            for (auto n:m.second) {
                int cur = check(n.second);
                resVal = max(resVal, cur);
            }
        }
    cout<< resVal<<endl;
    }
    return 0;
}

第五题:
图片说明
旅行商问题,利用动态规划可以求解
状态设置得比较有意思,利用二进制得知识求解

#include<vector>
#include<iostream>
using namespace std;
int helper(vector<vector<int>>& dis, vector<vector<int>>& dp, int city, int mode, int n) {
    if (dp[city][mode] != 20001) return dp[city][mode];
    if (mode == ((1<<n) - 1)) return dis[city][0];
    for (int i = 1, index = 0; i < (1<<n); i<<=1, index ++) {//一定要<<=而不是<<
        if ((mode | i) != mode) {
            dp[city][mode] = min(dp[city][mode], dis[city][index] + helper(dis, dp, index, (mode|i), n));
        }
    }
    return dp[city][mode];
}
int main() {
    int n = 0;
    cin >> n;
    vector<vector<int>> dis(n, vector<int> (n, 0));
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) cin>>dis[i][j];
    }
    int k = (1 << n) + 1;
    vector<vector<int>> dp(n, vector<int>(k, 20001));
    cout<<helper(dis, dp, 0, 1, n);
    return 0;
}

第六题:
图片说明
传统的动态规划,找零钱问题

#include<iostream>
#include<vector>
using namespace std;
int main() {
    int n = 0;
    cin>>n;
    int dp[1024 - n + 1];
    dp[0] = 0;
    for (int i = 1; i <= 1024 - n; i++) {
        dp[i] = 2048;
        dp[i] = min(dp[i], dp[i - 1] + 1);
        if (i >= 4) dp[i] = min(dp[i], dp[i - 4] + 1);
        if (i >= 16) dp[i] = min(dp[i], dp[i - 16] + 1);
        if (i >= 64) dp[i] = min(dp[i], dp[i - 64] + 1);
    }
    cout<<dp[1024 - n];
    return 0;
}

第七题:
图片说明
类似力扣地下城问题,要求反向dp

#include<iostream>
#include<vector>
using namespace std;
int main() {
    int n = 0;
    cin>>n;
    vector<int> H(n);
    for(int i = 0; i < n; i++) cin>>H[i];
    vector<int> dp(n + 1, 0);
    for (int i = n - 1; i >= 0; i --) dp[i] = (dp[i + 1] + H[i])/2;
    cout<<dp[0] + 1;
    return 0;
}

全部评论

相关推荐

10-14 23:01
已编辑
中国地质大学(武汉) Java
CUG芝士圈:虽然是网上的项目,但最好还是包装一下,然后现在大部分公司都在忙校招,十月底、十一月初会好找一些。最后,boss才沟通100家,别焦虑,我去年暑假找第一段实习的时候沟通了500➕才有面试,校友加油
点赞 评论 收藏
分享
11-11 14:21
西京学院 C++
无敌混子大王:首先一点,不管学校层次怎么样,教育经历放在第一页靠上位置,第一页看不到教育经历,hr基本直接扔掉了
点赞 评论 收藏
分享
点赞 1 评论
分享
牛客网
牛客企业服务