zzuli---1912---小火山的爱情密码

题目链接: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\n", ans);
    }
    return 0;
}

 

posted @ 2016-08-24 15:04  爱记录一切美好的微笑  阅读(219)  评论(0编辑  收藏  举报