尺取法 枚举区间

A - 炒鸡想减肥的字符串

Time Limit:1000MS    Memory Limit:65535KB    64bit IO Format:

SubmitStatusPracticeNBUT
1576

Description

从前,有一串很长很长的字符串,它由n个小写字母组成。

有一天它在照镜子的时候,觉得自己太肥了,于是它想减肥。减肥的时候,可以不断地去掉第一个或者最后一个字符。

它希望自己减肥之后,对于必须保持苗条系数M,苗条系数即必须包含‘a‘,‘b‘,‘c‘…… ‘a‘+M-1 这些字符,至少一个.

Input

第一行有一个数字T,表示组数。T <= 25

接下去每组有2个整数N,M. N <= 1000 表示字符串长度, M是苗条系数.

然后是一串由小写字母组成的字符串,字符串的长度n <= 1000。

Output

每行输出一个数字,表示该组数据求得的最小长度。对于不能减肥的小小骚年们,我们只能表示"I am so fat!".

Sample Input

3
5 3
ccbaa
11 3
abbbbdbbbbc
4 3
abba

Sample Output

3
11
I am so fat!

#include <cstdio>
#include <iostream>
#include <algorithm>
#include <queue>
#include <stack>
#include <climits>
#include <cstring>
#include <cmath>
#include <map>
#include <set>
#define INF 100000000

using namespace std;

int n,m;
char a[1005];
int num[30];

int main(){
	int t;
	cin >> t;
	while(t--){
		cin >> n >> m;
		scanf("%s",a);

		int s = 0;
		int e = 0;
		memset(num,0,sizeof(num));
		int cc = 0;

		int ans = INF;

		while(s < n){
			while(cc < m && e < n){
				if(a[e]-'a' < m && num[a[e]-'a'] == 0)
					cc++;
				num[a[e] - 'a'] ++;
				e++;
			}
			if((e-s) < ans && cc >= m) ans = e-s;
			num[a[s]-'a']--;
			if(a[s]-'a' < m && num[a[s]-'a'] == 0){
				cc--;
			}
			s++;
			if((e-s) < ans && cc >= m) ans = e-s;

		}
		if(ans == INF)
			cout << "I am so fat!"<< endl;
		else
			cout << ans << endl;
	}
	return 0;
}

时间: 2024-10-29 10:45:56

尺取法 枚举区间的相关文章

Hdu 5358 First One (尺取法+枚举)

题目链接: Hdu 5358 First One 题目描述: 数组a有n个元素,S[i,j]定义为a[i]+a[i+1]+.....+a[j],问:这个死东西等于多少? 解题思路: 二分肯定超,这个题目的时间卡的炒鸡严格,只有n*log(n)的复杂度才能过,n*log(n)^2都不可以的. 只需要枚举K,并且枚举区间左端i值,计算K的贡献值,然后遍历时候计算一下常数相加即可. 1 #include <cstdio> 2 #include <cstring> 3 #include &

poj 2100 尺取法 一个数字拆成连续数字平方和

题意:将一个数拆成若干个连续数字的平方和. 用尺取法枚举区间,复杂度为O(n),时限10s,3s多ac. 1 #include <iostream> 2 #include <cstring> 3 #include <cstdio> 4 #include <cmath> 5 using namespace std; 6 7 const int N = 100; 8 9 struct Node 10 { 11 int from, to; 12 } node[N]

luogu 1712 区间(线段树+尺取法)

题意:给出n个区间,求选择一些区间,使得一个点被覆盖的次数超过m次,最小的花费.花费指的是选择的区间中最大长度减去最小长度. 坐标值这么大,n比较小,显然需要离散化,需要一个技巧,把区间转化为半开半闭区间,然后线段树的每一个节点表示一个半开半闭区间. 接着我们注意到需要求最小的花费,且这个花费只与选择的区间集合中的最大长度和最小长度有关. 这意味着如果最大长度和最小长度一定,我们显然是需要把中间长度的区间尽量的选择进去使答案不会变的更劣. 不妨把区间按长度排序,枚举每个最小长度区间,然后最大区间

51nod-1686 第K大区间(二分+尺取法)

题目链接: 第K大区间 基准时间限制:1 秒 空间限制:131072 KB 定义一个区间的值为其众数出现的次数.现给出n个数,求将所有区间的值排序后,第K大的值为多少. Input 第一行两个数n和k(1<=n<=100000,k<=n*(n-1)/2) 第二行n个数,0<=每个数<2^31 Output 一个数表示答案. Input示例 4 2 1 2 3 2 Output示例 2 题意: 思路: 先把数组都离散为[1,n]的数,注意相等的;再二分答案t,check区间众数

51nod 1674 区间的价值V2(思维+拆位+尺取法)

最近被四区题暴虐... 题意:lyk拥有一个区间. 它规定一个区间的价值为这个区间中所有数and起来的值与这个区间所有数or起来的值的乘积. 例如3个数2,3,6.它们and起来的值为2,or起来的值为7,这个区间对答案的贡献为2*7=14. 现在lyk有一个n个数的序列,它想知道所有n*(n+1)/2个区间的贡献的和对1000000007取模后的结果是多少. 区间的and值和区间的or值相乘,实际上等于将and值分解为2的幂次和的形式与or值分解成2的幂次和的形式相乘. 所以对于同一段区间来说

hihocoder-1483区间价值 (二分+尺取法)

题目链接: 区间价值 给定n个数A1...An,小Ho想了解AL..AR中有多少对元素值相同.小Ho把这个数目定义为区间[L,R]的价值,用v[L,R]表示. 例如1 1 1 2 2这五个数所组成的区间的价值为4. 现在小Ho想知道在所有的的v[L,R](1 <= L <= R <= n)中,第k小的值是多少. Input 第一行一个数T(T<=10),表示数据组数. 对于每一组数据: 第一行两个数n,k(1<=n<=200,000,1<=k<=n*(n+1

HDU 6103 Kirinriki 枚举长度 尺取法

题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6103 题目描述: 定义两个相同长度的字符串的值为首尾开始字符串的ASCII相减, 求一个字符串中任取两个相同长度的不重叠的值不超过m的最大长度 解题思路: 求连续区间不超过某一个上限或者不低于某个下限的应该用尺取法 ,复杂度为O(n),  本题n是5000所以O(n^2)可行, 枚举前缀和后缀(通过枚举前缀, 再将字符串翻转枚举前缀进行), 再进行尺取 代码:  代码中有注释 #include <

poj 3320 Jessica&#39;s Reading Problem(尺取法+map/hash)

题目:http://poj.org/problem?id=3320 题意:给定N个元素的数组,找出最短的一段区间使得区间里面的元素种类等于整个数组的元素种类. 分析:暴力枚举区间的起点x,然后找到最小的y,使得区间[x,y]满足条件,x向有移位后变成x',现在的y'肯定不至于在y的左边.存状态的话map和hash都可以. map代码: #include <iostream> #include <set> #include <map> #include <cstdi

BestCoder Round #86 二,三题题解(尺取法)

第一题太水,跳过了. NanoApe Loves Sequence题目描述:退役狗 NanoApe 滚回去学文化课啦! 在数学课上,NanoApe 心痒痒又玩起了数列.他在纸上随便写了一个长度为 nnn 的数列,他又根据心情随便删了一个数,这样他得到了一个新的数列,然后他计算出了所有相邻两数的差的绝对值的最大值. 他当然知道这个最大值会随着他删了的数改变而改变,所以他想知道假如全部数被删除的概率是相等的话,差的绝对值的最大值的期望是多少. 输入描述 第一行为一个正整数 T,表示数据组数. 每组数