zoukankan      html  css  js  c++  java
  • 【ybtoj】【Hash】单词背诵

    题意

    题解

    首先是第一问,看到题感觉是不用Hash,直接用 map<string,int>就可以,但是怀疑常数大

    看了题解说先把每个单词的Hash值求出,再用 vis 数组判断是否出现过,但是我想了想这个 vis 数组也得用 map ,就感觉用Hash没什么意义,于是就没用 Hash

    第二问,一开始想到二分,check 函数里查询是O(n)的,总复杂度还是O(mlogm),应该也能过

    正解用尺取法,思路就是每次扩展到恰好区间内答案为第一问求得的最大值即可

    (这种移动区间求答案的题都可以想想尺取法

    代码

    单词背诵
    #include<bits/stdc++.h>
    using namespace std;
    #define ll long long
    const int INF = 0x3f3f3f3f,M = 1e5+10;
    int n,m,ans,now,len;
    char s1[M][12],s2[M][12];
    map<string,int> vis,vis2;
    int main()
    {
    	scanf("%d",&n);
    	for(int i=1;i<=n;i++) scanf("%s",s1[i]+1),vis[s1[i]+1]=1;
    	scanf("%d",&m);
    	for(int i=1;i<=m;i++) 
    	{
    		scanf("%s",s2[i]+1);
    		if(vis[s2[i]+1]==1) vis[s2[i]+1]++,ans++;
    	} 
    	len=INF;
    	int l=1,r=0;
    	if(!ans)
    	{
    		printf("0
    0");
    		return 0; 
    	}
    	
    	for(l=1;l<=m;l++)
    	{
    		if(l!=1&&vis2[s2[l-1]+1]&&vis[s2[l-1]+1]==2) vis2[s2[l-1]+1]--,now-=!vis2[s2[l-1]+1];
    		while(now<ans&&r<m)
    		{
    			r++;
    			if(!vis2[s2[r]+1]&&vis[s2[r]+1]==2) now++; 
    			vis2[s2[r]+1]++;
    		}
    		//printf("[%d,%d]:now=%d
    ",l,r,now);
    		if(r==m&&now<ans) break;
    		len=min(len,r-l+1);
    	}
    	printf("%d
    %d
    ",ans,len);
    	return 0;
    }
    
  • 相关阅读:
    信息检索重点关键字
    信息检索重点关键字
    信息检索重点关键字
    信息检索关键词部分
    信息检索关键词部分
    信息检索关键词部分
    输入五个国家的名称按字母顺序排列输出
    把一个整数按大小顺序插入已排好序的数组中
    快放假了
    清炒苦瓜
  • 原文地址:https://www.cnblogs.com/conprour/p/15233134.html
Copyright © 2011-2022 走看看