单词背诵(滑动窗口)

题目链接:https://www.luogu.com.cn/problem/P1381

题意:分别给你两个字符串的序列t和序列s,要求你输出在序列s与序列t有多少个相同的字符串,以及相同字符串子串的最小长度

思路:

类似于最小覆盖子串问题
滑动窗口+简单哈希
通过map来存储,序列t中出现的字符串在map中-1,当成欠款,
窗口右边往右滑直到欠债还清,此时窗口中序列满足条件,然后窗口左边再往右滑看能不能尽可能地缩短序列长度,记录答案
然后窗口右边再往右滑一个单位,看以这个位置结尾的最短覆盖长度,直到r>=m

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
int n,m;
int ans=INT_MAX;
int cnt=0;
map<string,int>mp;
int debt=0;
map<string,bool>ap;
const int maxn=1e5+5;
string arr[maxn];
signed main()
{
	ios::sync_with_stdio(false),cin.tie(0);
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		string s;cin>>s;
		mp[s]--;
	}
	
	cin>>m;
	for(int i=0;i<m;i++)
	{
	cin>>arr[i];
	if(!ap[arr[i]]&&mp[arr[i]]<0)
	{
		ap[arr[i]]=true;
		cnt++;
	}
}

	int temp=cnt;
	for(int l=0,r=0;r<m;r++)
	{
		if(mp[arr[r]]<0)
		{
			cnt--;
		}
		mp[arr[r]]++;
		if(cnt==0)
		{
			while(mp[arr[l]]>0)
			{
				mp[arr[l++]]--;
			}
			ans=min(ans,r-l+1);
		}
	}
	cout<<temp<<endl;
	cout<<ans<<endl;
	return 0;
}


posted @ 2025-01-03 15:32  Marinaco  阅读(18)  评论(0)    收藏  举报
//雪花飘落效果