hdu5056Boring count
Posted 那一抹落日的橙
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu5056Boring count相关的知识,希望对你有一定的参考价值。
之前一直没接触过尺取法,感觉还是可以理解的
我们可以设置一个完全满足题目要求的区间,然后从前往后不断加入元素,每加入一个元素,我们就要维护这个区间的正确性,如果加入新的元素之后,区间不满足要求,则将区间左端逐渐向右,直至这个区间符合题意为止,这样的做法是o(n)的
在这个题上,我们不断加入新的字母,如果发现这个区间不合法以后,则将其左端点不断右移,我们可以将其理解为,现在所求的,是以i这个位置为结尾的满足条件的子串数量,如果现在这个区间不合法,则说明左端点已经没有用了(因为之前需要它的时候已经都处理过了,向后走加入的字母更多,更与它无关),将其弹出
#include<iostream> #include<cstring> #include<cstdio> using namespace std; int he,ta,len,t,k,tot[30]; long long ans; char s[100010]; int main() { scanf("%d",&t); while(t--) { scanf("%s",s+1); len=strlen(s+1); he=1,ta=0,ans=0; scanf("%d",&k); memset(tot,0,sizeof(tot)); for(int i=1;i<=len;i++) { int lin=s[i]-‘a‘; tot[lin]++,ta++; if(tot[lin]>k&&he<ta)//如果一种字母的个数超过k,则说明区间不合法,将左端点向右移动 { while(tot[lin]>k)//直至这种字母个数不超过k tot[s[he++]-‘a‘]--; } ans+=(ta-he+1);//如果这个区间都满足条件了,那么在这个区间里,所有以i为结尾的子串也就全部满足条件,都应加进答案 } cout<<ans<<endl; } }
以上是关于hdu5056Boring count的主要内容,如果未能解决你的问题,请参考以下文章