STL刷题1

在这里插入图片描述# [TJOI2010] 阅读理解
题目入口

题目描述

英语老师留了 N N N 篇阅读理解作业,但是每篇英文短文都有很多生词需要查字典,为了节约时间,现在要做个统计,算一算某些生词都在哪几篇短文中出现过。

输入格式

第一行为整数 N N N ,表示短文篇数,其中每篇短文只含空格和小写字母。

按下来的 N N N 行,每行描述一篇短文。每行的开头是一个整数 L L L ,表示这篇短文由 L L L 个单词组成。接下来是 L L L 个单词,单词之间用一个空格分隔。

然后为一个整数 M M M ,表示要做几次询问。后面有 M M M 行,每行表示一个要统计的生词。

输出格式

对于每个生词输出一行,统计其在哪几篇短文中出现过,并按从小到大输出短文的序号,序号不应有重复,序号之间用一个空格隔开(注意第一个序号的前面和最后一个序号的后面不应有空格)。如果该单词一直没出现过,则输出一个空行。

样例 #1

样例输入 #1

3
9 you are a good boy ha ha o yeah
13 o my god you like bleach naruto one piece and so do i
11 but i do not think you will get all the points
5
you
i
o
all
naruto

样例输出 #1

1 2 3
2 3
1 2
3
2

提示

对于 30 % 30\% 30% 的数据, 1 ≤ M ≤ 1 0 3 1\le M\le 10^3 1M103

对于 100 % 100\% 100% 的数据, 1 ≤ M ≤ 1 0 4 1\le M\le 10^4 1M104 1 ≤ N ≤ 1 0 3 1\le N\le 10^3 1N103

每篇短文长度(含相邻单词之间的空格) ≤ 5 × 1 0 3 \le 5\times 10^3 5×103 字符,每个单词长度 ≤ 20 \le 20 20 字符。

每个测试点时限 2 2 2 秒。

感谢@钟梓俊添加的一组数据。

题解

用map+vector就可以做,记得去重,详见代码

Code

#include <bits/stdc++.h>

using namespace std;

// 定义两个整数变量 n 和 m
int n, m;
// 定义一个字符串变量 s
string s;
// 定义一个映射 mp,键为字符串,值为整数向量
map <string, vector<int> >mp;
// 定义一个映射 mp1,键为字符串,值为布尔型
map <string, bool>mp1;

// 读取数据的函数
void read()
{
    // 从标准输入读取一个整数 n
    cin >> n;
    // 进行 n 次循环
    for (int i = 1; i <= n; i++)
    {
        // 清空映射 mp1 中的数据
        mp1.clear();
        int L;
        // 读取一个整数 L
        cin >> L;
        // 当 L 不为 0 时进行循环
        while (L--)
        {
            // 读取一个字符串 s
            cin >> s;
            // 如果字符串 s 未曾在 mp1 中出现
            if (mp1[s] == 0)
            {
                // 将当前的索引 i 存入 mp 映射中对应 s 的向量中
                mp[s].push_back(i); 
                // 标记字符串 s 已出现
                mp1[s] = 1;
            }
        }
    }
}

// 解决问题的函数
void solve()
{
    // 从标准输入读取一个整数 m
    cin >> m;
    // 进行 m 次循环
    for (int i = 1; i <= m; i++)
    {
        // 读取一个字符串 s
        cin >> s;
        // 如果字符串 s 在 mp 中的向量不为空
        if (mp[s].size()!= 0)
        {
            // 输出向量中的第一个元素
            cout << mp[s][0];
        }
        // 遍历向量中除第一个元素外的其他元素
        for (int j = 1; j < mp[s].size(); j++)
        {
            // 输出其他元素,每个元素前加一个空格
            cout << " " << mp[s][j];
        }
        // 输出换行符
        cout << endl;
    }
}

// 主函数
int main()
{
    // 调用 read 函数读取数据
    read();
    // 调用 solve 函数解决问题
    solve();
    // 程序正常结束返回 0
    return 0;
}

### C++ STL 常用于力扣的数据结构与函数示例 #### 数据结构部分 C++ 的 Standard Template Library (STL) 提供了许多高效且易于使用的数据结构,这些工具非常适合解决 LeetCode 上的各种算法问1. **向量 `std::vector`** 向量是一个动态数组,能够自动调整大小并提供随机访问功能。它是许多目中最常用的基础容器之一。 ```cpp std::vector<int> vec; vec.push_back(10); // 添加元素到末尾 int value = vec.front(); // 访问第一个元素 ``` 2. **哈希表 `std::unordered_map`** 无序映射提供了平均时间复杂度为 O(1) 的键值存储和检索能力,在处理频率统计等问时非常有用。 ```cpp std::unordered_map<int, int> freqMap; freqMap[5]++; // 插入或更新键对应的计数值 if(freqMap.find(key)!=freqMap.end()) { /* 查找 */ } ``` 3. **集合 `std::set` / 多重集 `std::multiset`** 这些基于平衡二叉树实现的有序集合允许高效的去重以及范围查询操作。 ```cpp std::set<int> uniqueSet{7,8}; auto it = uniqueSet.insert(9).first; // 插入新元素并获取迭代器位置 bool exists = uniqueSet.count(7)>0 ? true : false ;// 判断是否存在某个特定值 ``` 4. **堆(优先队列)`std::priority_queue`** 使用大顶堆或者小顶堆来维护一组具有最高/最低优先级的对象列表,适用于求解最大最小K个数之类的问。 ```cpp std::priority_queue<int,std::vector<int>,std::greater<>> minHeap;// 小根堆定义方式 while(!minHeap.empty()){ cout<<minHeap.top()<<" "; // 输出当前堆顶元素 minHeap.pop(); } ``` 5. **双端队列 `std::deque`** 双端队列为两端都支持常数级别插入删除效率的理想选择,尤其适合滑动窗口类场景应用。 ```cpp deque<int> dq={1,2,3}; dq.emplace_front(-1); dq.emplace_back(4); ``` 6. **字符串流 `std::stringstream`** 字符串流可以帮助我们轻松完成格式化输入输出转换工作。 ```cpp string s="hello world"; stringstream ss(s); string word; while(ss>>word){ // 对每个单词做进一步处理... } ``` #### 排序与搜索函数 除了上述提到的标准模板库(STL),还有一些通用的功能性方法也值得了解: 1. **快速排序 `std::sort()` 或者自定义比较逻辑版本 `std::stable_sort()`** 能够方便快捷地对序列进行升序降序排列甚至更复杂的定制需求满足。 ```cpp vector<pair<int,int>> items={{3,'a'},{1,'b'}}; sort(items.begin(),items.end(), [](const pair<int,char>& a,const pair<int,char>& b)->bool{return a.first<b.first;} ); ``` 2. **二分查找 `std::binary_search`, `std::lower_bound`, `std::upper_bound`** 当目标区间已经处于有序状态时候,则可以通过这几个关联密切的方法加速定位过程。 3. **累积计算相关 `std::accumulate`** 方便地累加一系列数值总合或者其他形式的结果汇总运算。 ```cpp double avg= accumulate(v.begin(),v.end(),0)/double(v.size()); ``` 通过以上列举出来的几种核心组成部分及其简单实例演示可以看出,C++语言本身自带的强大工具箱确实极大地方便了开发者们构建解决方案流程. ```cpp #include <bits/stdc++.h> using namespace std; int main(){ // Example usage of some structures and algorithms discussed above. } ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值