今日头条后端编程题
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;
}


海康威视公司福利 1261人发布