360提前批笔试
一.选择题
基本不会做,好几个数学题加机器学习。
二.编程题
第一题:给你一个长度为50000的序列,你每次可以把一个数值的所有位置的数+一个v(v可以为正负),问你最少操作几次可以把这个序列变成相等的。
第二题:给你一个长度为100000的序列,再给你一个长度为k的操作序列,记每一次操作数为vi,每次都会当前这个序列小于vi的数放左边,大于的放右边,注意相对顺序是不能变的。
这个题考虑,小的数先排一定不会影响大的,因此我们考虑离线做,对操作数从小到大排序,对于每一个操作数,我们先把小于他的数按相对顺序放,然后再考虑放他自己,操作完成后那些没有被移动的数按相对顺序放即可。复杂度为O(nlogn)
#include "bits/stdc++.h"
using namespace std;
using pii = pair<int, int>;
int main() {
int n, m;
cin >> n;
vector<int> a(n), c(n);
map<int, deque<int>> mp;
for (int i = 0; i < n; i++) {
cin >> a[i];
mp[a[i]].push_back(i);
}
cin >> m;
vector<int> b(m);
for (int i = 0; i < m; i++) {
cin >> b[i];
}
sort(b.begin(), b.end());
vector<int> na;
for (int i = 0; i < m; i++) {
vector<int> val;
if (mp.size()) {
auto it = mp.begin();
while (it != mp.end() && it->first < b[i]) {
val.push_back(it->first);
it = next(it);
}
}
priority_queue<pii, vector<pii>, greater<pii>> Q;
for (auto &p : val) {
Q.push({mp[p].front(), p});
mp[p].pop_front();
}
while (!Q.empty()) {
auto [p, v] = Q.top();
Q.pop();
c[p] = true;
na.push_back(v);
if (!mp[v].size()) {
mp.erase(v);
} else {
Q.push({mp[v].front(), v});
mp[v].pop_front();
}
}
if (mp.count(b[i])) {
for (auto &p : mp[b[i]]) {
c[p] = true;
na.push_back(b[i]);
}
mp.erase(b[i]);
}
}
for (int i = 0; i < n; i++) {
if (!c[i]) {
na.push_back(a[i]);
}
}
a.swap(na);
for (int i = 0; i < n; i++) {
cout << a[i] << ' ';
}
return 0;
}
#360提前批笔试#
查看16道真题和解析