# [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 1≤M≤103 。
对于 100 % 100\% 100% 的数据, 1 ≤ M ≤ 1 0 4 1\le M\le 10^4 1≤M≤104, 1 ≤ N ≤ 1 0 3 1\le N\le 10^3 1≤N≤103 。
每篇短文长度(含相邻单词之间的空格) ≤ 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;
}
1011





