1912: 小火山的爱情密码
Time Limit: 1 Sec Memory Limit: 128 MBSubmit: 155 Solved: 38
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
#include <cstdio> #include <queue> #include <cstring> #define MAXN 10005 using namespace std; int sum[MAXN][27], re[MAXN], m, n, k; char s[MAXN], c[2]; bool judge1(int x, int y) { for (int i = 0; i < 26; i++) { if (!re[i]) continue; if (sum[x + y][i] - sum[x][i] + (s[x] == i + 'a') < re[i]) return false; } return true; } bool judge(int x) { if (x == 0) return false; for (int i = 0; i <= n - x; i++) { if (judge1(i, x-1)) return true; } return false; } int main() { int t; scanf("%d", &t); while (t--) { scanf("%d%d%s", &n, &m, s); memset(sum, 0, sizeof (sum)); sum[0][s[0]-'a']++; for (int i = 1; i < n; i++) { for (int j = 0; j < 26; j++) sum[i][j] += sum[i - 1][j]; sum[i][s[i]-'a']++; } memset(re, 0, sizeof(re)); for (int i = 0; i < m; i++) { scanf("%s%d", c, &k); re[c[0] - 'a'] = k; } int ub = n, lb = m, ans = -1; while (ub >= lb) { int mid = (ub + lb)>>1; if (judge(mid)) { ub = mid - 1;ans = mid; } else lb = mid + 1; } printf("%d ", ans); } return 0; }