L1-110 这不是字符串题(分数15😭以后就是20分了) 字符串处理

天梯赛L1-110传送门

题干太长,请点击传送门查看

解题思路

这里介绍几个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;
}
posted @ 2026-03-13 20:50  shuiwangrenjia  阅读(2)  评论(0)    收藏  举报