米哈游笔试前端9.14 AC C++
一个身高序列,排队,相邻两人身高平均数不是整数的,越多越好,输出最终队列
两种思路:
① 奇、偶身高分别一个栈,然后交替出栈入队,最后剩下的全入队。注意,因为每个人对左右都能产生共献,所以要人数多的先入队,比如【偶,奇,偶】
用到了O(N)的额外空间
#include <bits/stdc++.h>
using namespace std;
const size_t MAX_N = 100002;
uint a[MAX_N];
int main() {
int n;
cin >> n;
stack<uint> odd, even;
for(int i = 0; i < n; i++) {
cin >> a[i];
if(a[i] & 1) odd.push(a[i]);
else even.push(a[i]);
}
vector<uint> order;
while(odd.size() && even.size()) {
if(odd.size() > even.size()) {
order.push_back(odd.top());
order.push_back(even.top());
}
else {
order.push_back(even.top());
order.push_back(odd.top());
}
odd.pop();
even.pop();
}
while(odd.size()) {
order.push_back(odd.top());
odd.pop();
}
while(even.size()) {
order.push_back(even.top());
even.pop();
}
for(int i = 0; i < order.size(); i++)
cout << order[i] << (i == order.size() - 1 ? "\n" : " ");
return 0;
} ② 基本思路同上,但是奇偶各一个链表,少的往多的里面插,变成经典的合并链表,O(1)空间复杂度
代码略
给定字符串,查找存在连续k个"mihoyo"的最短字串,不存在输出-1,存在输出起始、末尾下标
基本思路:找到所有模式串的下标,保存到一个数组,然后按左右下标间隔k,遍历下标数组,计算最短长度
#include <bits/stdc++.h>
using namespace std;
const string TARGET = "mihoyo";
const size_t TARGET_LEN = TARGET.size();
int main() {
int n, k;
cin >> n >> k;
string str;
cin >> str;
vector<size_t> mihoyoPosition;
size_t p = -1;
// 全部出现位置
while((p = str.find(TARGET, p + 1)) != string::npos) mihoyoPosition.push_back(p);
// 不足k个
if(mihoyoPosition.size() < k) {
cout << "-1\n";
return 0;
}
// 找结果
pair<int, int> answer;
size_t minLength = UINT_MAX;
int l = 0, r = k - 1;
while(r < mihoyoPosition.size()) {
size_t len = mihoyoPosition[r] - mihoyoPosition[l];
if(len < minLength) {
minLength = len;
answer = {mihoyoPosition[l], mihoyoPosition[r] + TARGET_LEN - 1};
}
++l, ++r;
}
cout << answer.first << ' ' << answer.second << '\n';
return 0;
} 一个序列,每一次操作可以使一个数翻倍,使得序列成为严格递增的最少操作次数
计算每一个元素,严格大于前一个数需要翻倍的次数
设是
的下一个数
对于,可以解出
再考虑对于每一个数被翻倍后,后面的数理应同等地一起进行翻倍(或者说,需要先翻完前一个数翻倍的次数,再去做“为了大于前一个数而进行的翻倍”)
因此将每一个数需要的存到一个数组里,然后计算前缀和,最后再求和
仔细考虑特殊情况:
① ,即已经满足了严格递增,解出的
会是0或负数,负数实际有意义,说明前缀和累加到自己的时候,可以少翻几次。但是前缀和始终应当非负。
② 与
恰好差了2的幂次倍数,为了“严格递增”,
需要加一
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const size_t MAX_N = 100002;
int a[MAX_N], mark[MAX_N]; /* 记录每个数的k(大于前一个数需要翻倍的次数) */
int main() {
size_t n;
cin >> n;
for(int i = 0; i < n; i++) cin >> a[i];
for(int i = 1; i < n; i++) {
int k = int(ceil(log2(a[i - 1]) - log2(a[i])));
// 如果前后两个正好差2^t倍,多乘一个2(为了严格递增)
double t = log2(a[i - 1] * 1.0 / a[i]);
mark[i] = abs(ceil(t) - floor(t)) <= 1E-6 ? k + 1 : k;
}
LL ans = 0, sum = 0;
for(int i = 1; i < n; i++) {
sum = sum + mark[i];
if(sum < 0) sum = 0;
ans += sum;
}
cout << ans << '\n';
return 0;
} #笔试题目##米哈游笔试##米哈游秋招##米哈游23秋招笔试心得体会#
查看7道真题和解析
