第一题:吃鸡蛋
思路:直接暴力模拟
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int n, m;
cin >> n >> m;
int i;
for(i = 1;; i ++){
if(n == 0) break;
n --;
if(i % m == 0) n ++;
}
cout << i - 1 << endl;
return 0;
}
第二题:三仙归洞
思路:刚开始没有看清楚数据,直接暴力模拟,wa了一次,其实这题是找规律的,每进行六次操作就会和刚开始的一样,先将操作数模6,在模拟就可以了
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int n, x;
cin >> n >> x;
for(int i = n; i >= 1; i --){
if(i & 1){ //如果操作为奇数,中间与左边交换
if(x != 2) x = (x + 1) % 2;
}
else{ //操作为偶数,中间与右边交换
if(x != 0) x = 1 + x % 2;
}
}
cout << x << endl;
return 0;
}
第三题:构造数组
思路:这题我想到了先将a进行分段,最后的答案是2^(a的段数-1),原以为很简单的,没想到我才是小丑,这题主要的难点是分段,而且还有坑,会卡哈希表,分段主要是用两个哈希表分别来存储一个数刚开始出现的位置和最后出现的位置(啊啊啊,这我想了半天,就是没有想到用两个哈希表,我一直是想用一个来试),每个点的前后位置进行分段(放入一个数组中),最后区间合并求出分的段数再更根据前面的公式就可以求出了
代码:
#include <iostream>
#include <cstring>
#include <algorithm>
#include <unordered_map>
using namespace std;
typedef pair<int, int> PII;
const int N = 2e5 + 10, mod = 998244353;
PII q[N];
int main()
{
ios::sync_with_stdio(false);
cin.tie(0), cout.tie(0);
int n;
unordered_map<int, int> l(300000), r(300000); //这里会卡哈希表,设置哈希表的长度
cin >> n;
for(int i = 1; i <= n; i ++){
int x;
cin >> x;
r[x] = i; //x最后出现的位置
if(!l.count(x)) l[x] = i; //存储第一次出现的位置
}
int k = 0;
for(auto& [x, y] : l){
q[k ++] = {l[x], r[x]};
}
//区间合并
sort(q, q + k);
int cnt = 0;
for(int i = 0; i < k; i ++){
int j = i + 1, s = q[i].second;
while(j < k && q[j].first <= s) s = max(s, q[j ++].second);
cnt ++;
i = j - 1;
}
int res = 1;
for(int i = 0; i < cnt - 1; i ++){
res = (long long)res * 2 % mod;
}
cout << res;
return 0;
}
总结:在这次比赛中发现自己的数据结构还是不是很熟练,就map,unordered_map,set,unordered_set之间的区别不是很懂,但是通过这场比赛,我明白了这些的用法和区别,还有哈希表也会卡数据(感谢y总)。