[TJOI2010] 阅读理解
题目链接:
https://www.luogu.com.cn/problem/P3879
题目描述
思路1 (STL大法)
对每个单词,用map
来映射存储它所在的短文编号
用set
的好处:
-------1. 存储直接自动排序,操作简单(忽略效率)
-------2. 可能一个单词在一篇短文中出现多次,这里去重操作set
自带实现
#include <iostream>
#include <set>
#include <map>
#include <string>
using namespace std;
map<string, set<int> > m;int main() {int n;cin >> n;for(int i = 1; i <= n; i++) {int l;cin >> l;for(int j = 0; j < l; j++) {string word;cin >> word;m[word].insert(i);}}int p;cin >> p;while(p --) {string t;cin >> t;if(m.count(t)) {for(auto it = m[t].begin(); it != m[t].end(); it++)cout << *it << " ";cout << endl; }}return 0;
}
思路二(Tire树)
#include<cstdio>
#include<iostream>
#include<algorithm>
#include <bitset>using namespace std;int n,m;
char s[1001];
int l;
int tot=0;
int tri[300007][26];
bitset<1001> b[500007];inline void insert(char *s,int x){int rt=0;for(int i=0;s[i];i++){int v=s[i]-'a';if(!tri[rt][v]){tri[rt][v]=++tot;}rt=tri[rt][v];}b[rt][x]=1;
}inline void query(char *s){int rt=0;for(int i=0;s[i];i++){int v=s[i]-'a';if(!tri[rt][v]){cout<<' '<<endl;return;}rt=tri[rt][v];}for(int i=1;i<=n;i++){if(b[rt][i]==1){cout<<i<<' ';}}cout<<endl;
}int main(){cin>>n;for(int i=1;i<=n;i++){cin>>l;for(int j=1;j<=l;j++){cin>>s;insert(s,i);}}cin>>m;for(int i=1;i<=m;i++){cin>>s;query(s);}return 0;
}