[TJOI]2010阅读理解
题意:
- N N N个短文(字符串),每个字符串中有 L i L_i Li个单词。
- M M M个询问,每次询问有一个单词(字符串)。统计其在哪几篇短文中出现过,并按从小到大输出短文的序号,没有出现输出空行。
对于
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 字符。
思路:
思路比较直观的题.
代码思路:
- 考虑Hash丢到某个容器里查找.
暴力的复杂度 O ( n m l o g n ) O(nmlogn) O(nmlogn).
容器的选择 m a p map map会TLE, s e t set set能AC.
其他思路:
- 构建Trie树查询.
ps:需要开一个数组循环利用输出,防止MLE。
代码:
char s[60];
/**
* Hash 暴力枚举
* @return [description]
*/
ull gethash(char s[]){
int len=strlen(s);
//cout<<"len="<<len<<endl;
ull base=233;
ull has=0;
rep(i,0,len-1){
has=has*base+(s[i]);
}
return has;
}
std::set<ull>mp[1003];
int ans[10004];
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
int n;
cin>>n;
rep(j,1,n){
int l;
cin>>l;
rep(i,1,l){
cin>>s;
mp[j].insert(gethash(s));
}
}
int m;
cin>>m;
int cnt=0;
rep(i,1,m){
cin>>s;
ull ha=gethash(s);
rep(j,1,n){
if(mp[j].count(ha))ans[++cnt]=j;//set的计数函数
}
rep(h,1,cnt){//输出要求
if(h!=cnt)cout<<ans[h]<<" ";
else cout<<ans[h];
}
cout<<"\n";
cnt=0;
}
return 0;
}