L1-110 这不是字符串题(分数15😭以后就是20分了) 字符串处理
题干太长,请点击传送门查看
解题思路
这里介绍几个STL的函数:
-
search函数:定义于
<algorithm>库,适用于任何序列(凡是能排序的数据结构),可以按照一定逻辑进行查找本题中,在一段序列中查找某种连续序列 , 用法为 str.search( str.begin(),str.end() , tar.begin() , tar.end()) , 这里的str是整数数组的名称,
当然,考虑到数组大小不固定,使用vector,函数返回的是tar在str中第一次出现的位置,如果没有出现则返回str.end(); -
erase函数 + insert函数 == replace函数 : 前两者定义在
<vector>, 后者是 字符串 函数 ,不能用于vector数组。前两者的结合具有replace的
功能。本题中 , 设 index = search函数返回的值, str.erase(str.begin() + index , str.begin() + index + L1); 这里的L1是tar的大小
再用 str.insert(str.begin() + index , replace.begin() , replace.end())
格式有点难记
总结 : search(大起, 大终, 小起, 小终) , v.erase(起, 终) , v.insert(位置, 他起, 他终)
题解
#include <iostream>
#include <vector>
#include <algorithm> // 包含 search, reverse
#include <numeric> // 包含一些数值计算工具
using namespace std;
int main() {
// 1. 竞赛必背:关闭流同步,加速 cin/cout,防止超时
ios::sync_with_stdio(false);
cin.tie(0);
int N, M;
if (!(cin >> N >> M)) return 0; // 读取 N 和 M
// 使用 vector 存储序列,因为长度是动态变化的
vector<int> v(N);
for (int i = 0; i < N; ++i) {
cin >> v[i];
}
// 开始 M 次操作
while (M--) {
int type;
cin >> type;
if (type == 1) {
// --- 操作 1:查找并替换 ---
int L1;
cin >> L1;
vector<int> target(L1);
for (int i = 0; i < L1; ++i) cin >> target[i];
int L2;
cin >> L2;
vector<int> replacement(L2);
for (int i = 0; i < L2; ++i) cin >> replacement[i];
// 使用 STL 的 search 查找 target 在 v 中第一次出现的位置
auto it = search(v.begin(), v.end(), target.begin(), target.end());
// 如果找到了 (it 不等于 v.end())
if (it != v.end()) {
// 计算一下当前找到的位置下标,因为 erase 后迭代器会变,用下标重新定位更稳
int index = distance(v.begin(), it);
// 1. 删除旧的:从 index 开始,删除 L1 个元素
v.erase(v.begin() + index, v.begin() + index + target.size());
// 2. 插入新的:在同个位置插入 replacement 序列
v.insert(v.begin() + index, replacement.begin(), replacement.end());
}
// 如果没找到,什么都不做,符合题目要求
}
else if (type == 2) {
// --- 操作 2:相邻和为偶数插入平均数 ---
// 致命陷阱预警:不要在原 vector 遍历时直接 insert!
// 解决方案:构造一个新的 vector
vector<int> next_v;
// 防止空 vector 导致越界
if (!v.empty()) {
for (size_t i = 0; i < v.size() - 1; ++i) {
next_v.push_back(v[i]); // 先把当前的数放进去
long long sum = (long long)v[i] + v[i+1]; // 防溢出(虽然题目数据不大,但要养成习惯)
if (sum % 2 == 0) {
next_v.push_back(sum / 2); // 插入平均数
}
}
// 别忘了把最后一个数放进去,因为它后面没有数了,不会参与计算
next_v.push_back(v.back());
}
v = next_v; // 更新主序列
}
else if (type == 3) {
// --- 操作 3:区间翻转 ---
int l, r;
cin >> l >> r;
// 题目下标从 1 开始,C++ 是 0 开始。
// reverse 区间是左闭右开 [first, last)
// 所以左边是 l-1,右边是 r (因为 r 对应下标 r-1,右开区间取 r 刚好包住 r-1)
if (l < r && r <= v.size()) { // 简单的边界保护
reverse(v.begin() + l - 1, v.begin() + r);
}
}
}
// --- 输出结果 ---
for (size_t i = 0; i < v.size(); ++i) {
// 控制空格:最后一个数后面不要空格
cout << v[i] << (i == v.size() - 1 ? "" : " ");
}
cout << endl;
return 0;
}

浙公网安备 33010602011771号