今日头条后端编程题

1、串珠,滑动窗口的应用
#include <bits/stdc++.h>
using namespace std;

int n, m, c;

vector<int> colors[20008];
int win[1008];

int solution() {
    unordered_set<int> cc;
    memset(win, 0, sizeof win);
    for (int i = 0; i < m; ++i) {
        for (int c : colors[i]) {
            win[c]++;
            if (win[c] > 1)
                cc.emplace(c);
        }
    }
    for (int i = 1; i < n; ++i) {
        for (int c : colors[i-1])
            win[c]--;
        for (int c : colors[i+m-1]) {
            win[c]++;
            if (win[c] > 1)
                cc.emplace(c);
        }
    }
    return cc.size();
}

int main() {
    // freopen("in.txt", "r", stdin);
    int num, c;
    while (~scanf("%d%d%d", &n, &m, &c)) {
        for (int i = 0; i < n; ++i) {
            colors[i].clear();
            colors[i+n].clear();
            scanf("%d", &num);
            while (num--) {
                scanf("%d", &c);
                colors[i].emplace_back(c);
                colors[i+n].emplace_back(c);
            }
        }
        printf("%d\n", solution());
    }
    return 0;
}
2、喜爱程度的统计,线段树模板题,注意别爆内存
#include <bits/stdc++.h>
using namespace std;

constexpr int MAXN = 300008;

struct Node {
    unordered_map<int, int> cnts;
    int l, r;
} nodes[MAXN];

int n, q;
int ks[MAXN];

void build(int b, int e, int root) {
    nodes[root].l = b, nodes[root].r = e;
    if (e - b <= 10) { //防止爆内存。。。
        for (int i = b; i <= e; ++i) {
            nodes[root].cnts[ks[i]]++;
        }
        return ;
    }
    int lc = root << 1;
    int rc = lc | 1;
    int mid = b + (e - b >> 1);
    build(b, mid, lc);
    build(mid+1, e, rc);
    if (nodes[lc].cnts.empty()) {
        for (int i = b; i <= mid; ++i) {
            nodes[root].cnts[ks[i]]++;
        }
    } else {
        for (auto p : nodes[lc].cnts) {
            nodes[root].cnts[p.first] += p.second;
        }
    }
    if (nodes[rc].cnts.empty()) {
        for (int i = mid+1; i <= e; ++i) {
            nodes[root].cnts[ks[i]]++;
        }
    } else {
        for (auto p : nodes[rc].cnts) {
            nodes[root].cnts[p.first] += p.second;
        }
    }
}

int query(int l, int r, int k, int root) {
    if (r - l <= 10) {
        int cnt = 0;
        for (int i = l; i <= r; ++i) {
            if (ks[i] == k)
                cnt++;
        }
        return cnt;
    }
    if (l == nodes[root].l && r == nodes[root].r)
        return nodes[root].cnts[k];
    int m = nodes[root].l + (nodes[root].r - nodes[root].l >> 1);
    int lc = root << 1;
    int rc = lc | 1;
    if (r <= m) return query(l, r, k, lc);
    else if (l > m) return query(l, r, k, rc);
    else return query(l, m, k, lc) + query(m+1, r, k, rc);
}

int main() {
    // freopen("in.txt", "r", stdin);
    int l, r, k;
    while (~scanf("%d", &n)) {
        for (int i = 1; i <= n; ++i)
            scanf("%d", ks + i);
        build(1, n, 1);
        scanf("%d", &q);
        while (q--) {
            scanf("%d%d%d", &l, &r, &k);
            printf("%d\n", query(l, r, k, 1));
        }
    }
    return 0;
}
附加题、少于m次交换的最长连续字符串。类似暴力,比如ababa,枚举每个字母,将其它相同的字母移到以这个字母为中心需要的操作次数,用了些trick优化。居然过了。。。
#include <bits/stdc++.h>
using namespace std;

int m;
string s;
vector<int> axis[32];

void preprocess() {
    for (int i = 0; i < s.size(); ++i) {
        axis[s[i]-'a'].emplace_back(i);
    }
}

int solution(char ch) {
    int idx = ch - 'a';
    int n = axis[idx].size();
    int maxi = 1;
    for (int i = 0; i < n; ++i) {
        int con = 1;
        int cur = 0;
        int lc = i, rc = n - 1 - i;
        int la = axis[idx][i] - 1, ra = axis[idx][i] + 1;
        int left = i - 1, right = i + 1;
        while (true) {
            int a = m + 1, b = m + 1;
            if (left >= 0 && lc > 0) {
                a = la - axis[idx][left];
            }
            if (right < n && rc > 0) {
                b = axis[idx][right] - ra;
            }
            if (min(a, b) + cur > m) break;
            if (a < b) {
                la--;
                lc--;
                left--;
            } else {
                ra++;
                rc--;
                right++;
            }
            con++;
            cur += min(a, b);
        }
        maxi = max(maxi, con);
    }
    return maxi;
}

int main() {
    // freopen("in.txt", "r", stdin);
    while (cin >> s >> m) {
        vector<pair<int, char>> v(32, make_pair(0, ' '));
        for (int i = 0; i < 26; ++i)
            axis[i].clear();
        for (char ch : s) {
            v[ch-'a'].first++;
            v[ch-'a'].second = ch;
        }
        sort(v.begin(), v.end());
        preprocess();
        int s = 1;
        for (auto it = v.rbegin(); it != v.rend(); ++it) {
            if (s >= it->first)
                break;
            s = solution(it->second);
        }
        cout << s << '\n';
    }
    return 0;
}

#字节跳动#
全部评论
大神厉害
点赞 回复 分享
发布于 2017-09-10 21:12
大神,膜拜
点赞 回复 分享
发布于 2017-09-10 21:15
膜拜
点赞 回复 分享
发布于 2017-09-10 21:16
膜大佬!我第二题线段树爆内存了。。。只过了80%,当时没想到防止爆内存的方法。。。学习了!
点赞 回复 分享
发布于 2017-09-10 21:17
膜acm大佬。
点赞 回复 分享
发布于 2017-09-10 21:18
附加题也是这样做的。。。居然只有5%
点赞 回复 分享
发布于 2017-09-10 21:20
第二题线段树 超时 只过了50%
点赞 回复 分享
发布于 2017-09-10 23:25

相关推荐

牛客717484937号:双飞硕没实习挺要命的
点赞 评论 收藏
分享
5 收藏 评论
分享
牛客网
牛客企业服务