[TJOI]2010阅读理解(简单Hash+STL)

[TJOI]2010阅读理解

题意:

  • \(N\)个短文(字符串),每个字符串中有\(L_i\)个单词。
  • \(M\)个询问,每次询问有一个单词(字符串)。统计其在哪几篇短文中出现过,并按从小到大输出短文的序号,没有出现输出空行。

对于 \(30\%\)的数据,\(1\le M\le 10^3\).
对于 \(100\%\) 的数据,\(1\le M\le 10^4\)\(1\le N\le 10^3\)
每篇短文长度(含相邻单词之间的空格)\(\le 5\times 10^3\)字符,每个单词长度 \(\le 20\) 字符。

思路:

思路比较直观的题.

代码思路:

  • 考虑Hash丢到某个容器里查找.
    暴力的复杂度\(O(nmlogn)\).
    容器的选择\(map\)会TLE,\(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;
}
posted @ 2020-07-12 11:39  Qquun  阅读(38)  评论(0)    收藏  举报