寒武纪 9.19笔试题C++题解
第一题
分数的上取整
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int fun(int x) {
if (x < 38) return x;
int y = x;
while (y % 5 != 0) y++;
if ((y - x) < 3) return y;
return x;
}
int main() {
//
ll n;
cin >> n;
int x;
while (n--) {
cin >> x;
cout << fun(x) << endl;
}
return 0;
} 第二题
区间修改,单点查询,用查分数组做
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int n, m; // 列表长度为N,M个操作
void fun(ll diff[], int a, int b, int k) {
// a b之间的元素增加k
diff[a] += k;
diff[b + 1] -= k;
}
void cal(ll arr[], ll diff[]) {
for (int i = 1; i <= n; i++) { arr[i] = arr[i - 1] + diff[i]; }
}
#define show(x, idx, n) \
for (int i = idx; i < n; i++) cout << x[i] << ' '; \
cout << endl;
int main() {
//
cin >> n >> m;
ll arr[n + 1];
ll diff[n + 2]; // 差分数组
// diff[1] = arr[1]-arr[0];
// arr[1] = arr[0]+diff[1];
memset(arr, 0, sizeof(arr));
memset(diff, 0, sizeof(diff));
int a, b, k;
while (m--) {
cin >> a >> b >> k;
fun(diff, a, b, k);
// cal(arr, diff);
// show(arr, 1, n + 1);
}
cal(arr, diff);
// int res = max_element(arr+1, arr+n+1);
ll res = arr[1];
// show(arr, 1, n + 1);
for (int i = 2; i <= n; i++) { res = max(res, arr[i]); }
cout << res;
return 0;
} 第三题
pop出数组里最小的两个数a,b push进 a+2b
用最小堆做,这里有一个坑
当最后只有一个数,找不到第二小的数,不能使得所有数都大于k时,输出-1
题目里没有讲,自己试出来的,没有考虑到这条只能过55.56%
#include <bits/stdc++.h>
using namespace std;
#define ll long long
int main() {
//
ll k;
int n;
cin >> n >> k;
ll t;
priority_queue<ll, vector<ll>, greater<ll>> q;
for (int i = 0; i < n; i++) {
cin >> t;
q.emplace(t);
}
int res = 0;
while (!q.empty() && q.top() < k) {
res++;
ll x = q.top();
q.pop();
ll y;
if (q.empty()) {
y = x;
} else {
y = q.top();
q.pop();
}
ll z = x + 2 * y;
q.emplace(z);
}
cout << res;
return 0;
} 第四题
求至少交换多少次使得数组有序,一开始只想到升序,过了60%,其实降序也可以。
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define show(x, idx, n) \
for (int i = idx; i < n; i++) cout << x[i] << ' '; \
cout << endl;
int res = 0;
int n;
void fun(vector<int> &arr, int idx, int x) {
// 当前的索引是idx,它的值是x
// 如果idx==x 直接结束
if (idx == x) return;
res++;
// 否则, 把x调整到x的位置
swap(arr[idx], arr[x]);
// 此时arr[idx]被调整到了合适的位置
// 但是当前位置idx又不对了
// show(arr, 0, n);
fun(arr, idx, arr[idx]);
}
int main() {
//
cin >> n;
vector<int> arr(n);
for (int i = 0; i < n; i++) { cin >> arr[i]; }
vector<int> arr2(arr);
vector<int> arr3(arr);
sort(arr2.begin(), arr2.end());
unordered_map<int, queue<int>> mp(n);
for (int i = 0; i < n; i++) { mp[arr2[i]].emplace(i); }
for (int i = 0; i < n; i++) {
int x = arr[i];
arr[i] = mp[x].front();
mp[x].pop();
}
// show(arr2, 0, n);
// show(arr, 0, n);
for (int i = 0; i < n; i++) { fun(arr, i, arr[i]); }
int ans = res;
// cout << res;
// cout << endl;
sort(arr2.begin(), arr2.end(), greater<int>());
unordered_map<int, queue<int>> mp1(n);
for (int i = 0; i < n; i++) { mp1[arr2[i]].emplace(i); }
for (int i = 0; i < n; i++) {
int x = arr3[i];
arr3[i] = mp1[x].front();
mp1[x].pop();
}
// cout << res;
// show(arr2, 0, n);
// show(arr3, 0, n);
res = 0;
for (int i = 0; i < n; i++) { fun(arr3, i, arr3[i]); }
// cout << res;
// cout << endl;
cout << min(ans, res);
return 0;
} 