[TJOI2010]阅读理解
题目描述
英语老师留了N篇阅读理解作业,但是每篇英文短文都有很多生词需要查字典,为了节约时间,现在要做个统计,算一算某些生词都在哪几篇短文中出现过。
输入格式
第一行为整数N,表示短文篇数,其中每篇短文只含空格和小写字母。
按下来的N行,每行描述一篇短文。每行的开头是一个整数L,表示这篇短文由L个单词组成。接下来是L个单词,单词之间用一个空格分隔。
然后为一个整数M,表示要做几次询问。后面有M行,每行表示一个要统计的生词。
输出格式
对于每个生词输出一行,统计其在哪几篇短文中出现过,并按从小到大输出短文的序号,序号不应有重复,序号之间用一个空格隔开(注意第一个序号的前面和最后一个序号的后面不应有空格)。如果该单词一直没出现过,则输出一个空行。
输入 #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
解法一:
STL+思维;
这里用到了map<string ,vector< int> > ma,比一般的map多了一个存储功能;非常好用;
调用vector里面的数要用ma[i].size();
代码:
#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define lson k<<1
#define rson k<<1|1
//ios::sync_with_stdio(false);
using namespace std;
const int N=500100;
const int M=50100;
const LL mod=1e9+7;
map<string,vector<int> >ma;
int main(){
ios::sync_with_stdio(false);
int n,l;
cin>>n;
for(int i=1;i<=n;i++){
cin>>l;
for(int j=1;j<=l;j++){
string s;
cin>>s;
ma[s].push_back(i);
}
}
int m;
cin>>m;
for(int i=1;i<=m;i++){
string s;
cin>>s;
if(ma[s].empty()) cout<<endl;
else{
cout<<ma[s][0]<<” “;
for(int j=1;j<ma[s].size();j++){
if(ma[s][j]!=ma[s][j-1]) cout<<ma[s][j]<<” “;
}
cout<<endl;
}
}
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
解法二:
字典树
这道题的空间消耗有点大,如果记录数组用bool型都会MLE,改成bitset就行;
这道题跟模板题的区别,就是哪个记录数组用的非常巧妙,val[x][p],x代表第树的第几层,也表示那个单词,p代表第几行,然后赋值为1,表示这个单词在第几行出现过;
代码:
#include<bits/stdc++.h>
#define LL long long
#define pa pair<int,int>
#define lson k<<1
#define rson k<<1|1
//ios::sync_with_stdio(false);
using namespace std;
const int N=500100;
const int M=50100;
const LL mod=1e9+7;
int tr[N][30];
bitset<1005>val[N];
int rt;
int n,l,m;
void add(string s,int p){
int k=0;
for(int i=0;i<s.length();i++){
int d=s[i]-‘a’;
if(!tr[k][d]) tr[k][d]=++rt;
k=tr[k][d];
}
val[k][p]=1;
}
void search(string s){
int k=0;
int flag=1;
for(int i=0;i<s.length();i++){
int d=s[i]-‘a’;
if(!tr[k][d]){
flag=0;
break;
}
k=tr[k][d];
}
if(flag){
for(int i=1;i<=n;i++){
if(val[k][i]==1) cout<<i<<” “;
}
}
cout<<endl;
}
int main(){
ios::sync_with_stdio(false);
cin>>n;
for(int i=1;i<=n;i++){
cin>>l;
for(int j=1;j<=l;j++){
string s;
cin>>s;
add(s,i);
}
}
cin>>m;
for(int i=1;i<=m;i++){
string s;
cin>>s;
search(s);
}
return 0;
}