题解单词背诵

Posted h-lka

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了题解单词背诵相关的知识,希望对你有一定的参考价值。

QUESTION_POS

本来想用(trie)的,结果有一个神奇的数组赋值无效……

思路:先求出第一问答案,可以(O(n))一遍扫出来,注意背诵的单词只统计一次

难点在于第二问。

可以用单调队列扫一下,记录队列中每个单词在文章中的位置,对于队头,如果这里的单词在后面出现过,队头就可以不要了。

当队伍中单词达到数量时,可以统计答案了。

#include<cstdio>
#include<cstring>
#include<iostream>
#include<string>
#include<map>
using namespace std;
int head=1,tail,n,m,cnt,ans;
int tot,q[100010],a[100010];
int b[100010],vis[100010];
char ch[21];
map<string,int>mp;
const int inf=2147483647;
int main(){
    ans=inf;
    scanf("%d",&n);
    for(int i=1;i<=n;++i){
        scanf("%s",ch);
        mp[ch]=i;
    }
    scanf("%d",&m);
    for(int i=1;i<=m;++i){
        scanf("%s",ch);
        a[i]=mp[ch];
        if(!a[i])continue;
        if(!vis[a[i]]){
            vis[a[i]]=1;
            tot++;
        }//找出现过的所有单词
        //也可以用trie 
    }
    if(!tot){//特判,因为tail-head最小是1,不特判WA一个点 
        printf("0
0");
        return 0;
    }
    for(int i=1;i<=m;++i){
        if(!b[a[i]]&&a[i])cnt++;
        b[a[i]]=i,q[++tail]=i;
        //b数组存的是当前要背单词在队列中最靠后的位置
        //q数组存的是当前队列中有的要背单词的文章中pos
        //如果当前队列里面有值并且当前队头的单词在后面出现过
        //可以去掉队头,指针后移
        //当队伍中已经包含所有单词时
        //更新答案 
        while(head<=tail&&q[head]<b[a[q[head]]])head++;
        if(cnt==tot)ans=min(ans,tail-head+1);
    }
    printf("%d
%d",tot,ans);
    return 0;
}

以上是关于题解单词背诵的主要内容,如果未能解决你的问题,请参考以下文章

题解 P1381 单词背诵(哈希,队列)

CODEVS——T 3013 单词背诵

android项目实战-背呗单词DEV06-单词背诵实现

单词背诵

[CODEVS3031] 单词背诵 - 字符串hash

codevs 3013 单词背诵 hash