zoukankan      html  css  js  c++  java
  • 【题解】单词背诵

    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;
    }
    
  • 相关阅读:
    收集一些特殊的符号
    腾讯笔试有感
    Lazy Load, 延迟加载图片的 jQuery 插件
    腾讯实习生笔试题
    IE捉迷藏bug详解(躲猫猫)
    使用SQL Server 2000 全文检索
    一篇比较不错的关于masterpage的文章
    ASP.NET中对表单输入行有选择验证
    在WSS中高亮显示搜索结果
    WebPart安装位置对FrontPager的影响
  • 原文地址:https://www.cnblogs.com/h-lka/p/12179563.html
Copyright © 2011-2022 走看看