洛谷——P3879 [TJOI2010] 阅读理解(STL:hash+set,c++)
一、题目
[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 秒。
感谢@钟梓俊添加的一组数据。
二、题解
基本思路:
- 这道题要统计单词在哪几篇短文中出现过,序号不能重复且按从小到大输出短文的序号。
- (1).有没有出现过可以用哈希来判断。
- (2).序号不能重复且按从小到大输出短文的序号,很显然这里可以用STL中的set(集合)来存放序号。
- (3).那么该怎么把哈希和set结合起来呢?这里我做了一番尝试,既然之前写的时候遇到了unordered_map<int,vector> ,那么一定也可以有unordered_map<int,set>,这样就结合在一起了。
代码
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0)
#define endl "\n"
#define int long long
#define repn(i,o,n) for(int i=o;i<=n;i++)
#define rep(i,o,n) for(int i=o;i<n;i++)
void solve(){
unordered_map<string,set<int>> mp;
int n,m;
cin>>n;
repn(i,1,n){
int L;
cin>>L;
repn(j,1,L){
string str;
cin>>str;
//单词序号插入到该单词对应的序号集合
mp[str].insert(i);
}
}
cin>>m;
while(m--){
string str;
cin>>str;
if(mp[str].empty()){
cout<<endl;//不存在要输出空行,注意是空行哦!(bushi空格T_T)
continue;
}
bool flag=false;
for(auto i:mp[str]){//输出
if(flag) cout<<" ";
cout<<i;
flag=true;
}
cout<<endl;
}
}
signed main(){
IOS;
int T=1;
//cin>>T;
while(T--){
solve();
}
return 0;
}
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!