题目链接:http://acm.zzuli.edu.cn/zzuliacm/problem.php?id=1912
Description 小火山获得了一个字符串,然而大火山让小火山从里面截取一段字符串,并且让小火山截取的字符串满足一些字符达到一定数量。 小火山觉得很容易,但是他想要知道他至少得截取多长的字符串。 Input 首先是一个整数t(t<=100),表示测试数据组数。接下来是两个整数n和m(n<=10000, m<=10),n表示字符串的长度,m表示要满足一定数量的字符 的种类.(字符只包含小写英文字母) 个数(没有重复字符种类),然后有m行,每行第一个是一个字符,然后是一个整数x(x<=50),表示这种字符的的要求数量。 Output 输出最小长度,如果达不到要求输出-1 Sample Input 1 6 3 cancan c 2 a 2 n 2
Sample Output 6
HINT Source zzuli
#include <cstdio> #include <cstring> #include <iostream> #include <cmath> #include<vector> #include<queue> #include<algorithm> using namespace std; typedef long long LL; const int maxn=50009; const int INF=0x3f3f3f3f; const int mod=2009; char str[maxn]; int n, m; int a[maxn], b[maxn]; int judge() { for(int i=0; i<26; i++) { if(b[i] < a[i]) return 0; } return 1; } int main() { int T; scanf("%d", &T); while(T--) { scanf("%d %d %s", &n, &m, str); char ch; int k, cnt=0, ans=INF; memset(a, 0, sizeof(a)); memset(b, 0, sizeof(b)); for(int i=0; i<m; i++) { scanf(" %c%d", &ch, &k); a[ch-'a']=k; } for(int i=0; i<n; i++) { b[str[i]-'a']++; while(judge()) { ans=min(ans, i+1-cnt); b[str[cnt]-'a']--;///退出循环 cnt++;///往后查找 } } if(ans==INF) ans=-1; printf("%d ", ans); } return 0; }