YbtOJ hash和hash表课堂过关 例4 单词背诵【hash】【二分】
发布日期:2021-05-07 13:10:05 浏览次数:10 分类:原创文章

本文共 1575 字,大约阅读时间需要 5 分钟。

在这里插入图片描述

思路

首先把需要背诵的单词存入 h a s h hash hash 表。
然后我们要把单词表里的单词先扫一遍,统计出最坏长度的答案。
然后用尺取法,不断向右移动 r r r, 当当前长度已经可以得到最坏长度的答案,就更行长度,然后把l向右移到一个单词出列(遇到相同单词继续移)。
注意:单词表中的单词可能不需要背诵!

代码

#include<algorithm>#include<iostream>#include<cstdio>using namespace std;int wz[100010],t[100010],t2[100010];unsigned long long js;string s[100010];int n,m,ans,ansjl;struct node{   	unsigned long long hash1,hash2;	long long bj; }a[100010];bool cmp(const node&df,const node&df2){   	return df.hash1<df2.hash1;}int main(){       cin>>n;    for(int i=1; i<=n; i++)     {        	cin>>s[i];     	a[i].bj=i;     	int lon=s[i].size();     	for(int j=0; j<=lon-1; j++)     	   a[i].hash1=a[i].hash1*131ull+(s[i][j]-43);	 }	sort(a+1,a+1+n,cmp);	cin>>m;	for(int i=1; i<=m; i++)	 {   	 	cin>>s[i];	 	int lon=s[i].size();	 	wz[i]=-1,js=0;   //初始化-1,如果出现主义中的状况就可直接判断	 	for(int j=0; j<=lon-1; j++)	 	   js=js*131ull+(s[i][j]-43);	 	int l=1,r=n,mid=0;	 	while(l<=r)	 	 {   	 	 	mid=(l+r)>>1; 	 	 	if(js<a[mid].hash1)	 	 	  r=mid-1;	 	 	else if(js>a[mid].hash1)	 	 	  l=mid+1;	 	 	else	 	 	 {   	 	 	 	wz[i]=a[mid].bj;	 	 	 	break;			 }		 }		if(t[wz[i]]==0&&!(wz[i]==-1))		 {   		 	t[wz[i]]=1;		 	ans++;		 }	 }	cout<<ans;	ansjl=m;	int l=1,ans2=0;	for(int r=1; r<=m; r++)	 {   	 	if(wz[r]!=-1)	 	 {   	 	 	if(t2[wz[r]]==0)	 	 	  ans2++;	 	 	t2[wz[r]]++;	 	    if(wz[l]!=-1)	 	     {   	 	       while(l<=r&&ans2==ans)	 	        {   	 	        	t2[wz[l]]--;	 	        	if(t2[wz[l]]==0)	 	        	 {   	 	        	 	ansjl=min(ansjl,r-l+1);	 	        	 	ans2--;					 }					l++;		        }			 }			 }	 }	cout<<endl<<ansjl;	return 0;}
上一篇:YbtOJ hash和hash表课堂过关 例5 子正方形【hash】【二分】
下一篇:Luogu P1164 小A点菜 & P1044 栈【基础动态规划】

发表评论

最新留言

很好
[***.229.124.182]2025年04月05日 19时40分30秒