题目描述
小科是一名作家,他正在写一篇英文小说,可以将他的小说看成一个长长的字符串。然而不幸的是小科的键盘出了点问题,有部分按键无法使用了,确切地说只有M个按键是可以使用的。给定小科的小说内容,请帮助小科计算,如果M个可用的按键可以由小科指定的话,那么他可以输入的最长连续序列有多长。
输入格式
输入包含多组数据,对于每组数据:
第1行:一个整数M,表示有M个按键可用,当M等于0时表示输入结束。
第2行:一个字符串,表示小科想要写的小说(可能包含空格、标点符号等,不包括换行)。
输出格式
对于每组数据输出一行:表示小科可以输入的最长连续序列(小说的一部分)。
输入输出样列
输入样例1:
5 hello world! 0
输出样例1:
8
说明
【样例说明】
小科可以选择5个可用的键,小科选择'l', 'o', 'w', 'r', ' '(空格)。可以输出"llo worl"共8个连续字符。
【数据范围】
1 <= M <= 128;1 <= 小说的长度 <= 1000000;
【耗时限制】1000ms 【内存限制】128MB
原题链接:科丁乐|OJ平台
解题思路:
1.朴素枚举:枚举所有子序列[l, r],判断[l, r]中不同字符的数量是否<=m,找出满足条件的最长子序列。
时间复杂度:O(N^3),N最大10^6,肯定超时!
2.如果序列[l, r]里面不同字符超过了m,那么[l, r+1]中不同字符的数量一定也超过了m个
枚举区间右端点r,计算以r为右端点时,满足不同字符数量<=m的区间最长有多长。
如果cnt[l, r] > s,那么此时a[l]是需要删除的,并且对于[l, r+1]来说l也是需要删除的。
详细代码:
#include<bits/stdc++.h>
using namespace std;
int m,cnt[1000001];
string s;
int main()
{
while(cin>>m&&m!=0)
{
cin.get();
getline(cin,s);
int n=s.size();
memset(cnt,0,sizeof(cnt));
int l=0,ans=0,sum=0;
for(int r=0;r<n;r++)
{
cnt[s[r]]++;
if(cnt[s[r]]==1) sum++;
while(l<r&&sum>m)
{
cnt[s[l]]--;
if(cnt[s[l]]==0) sum--;
l++;
}
ans=max(ans,r-l+1);
}
cout<<ans<<endl;
}
return 0;
}
这题就是这么简单,我们下题再见!
其他专栏链接:https://blog.csdn.net/gks_zzx/category_11088899.html?spm=1001.2014.3001.5482
https://blog.csdn.net/gks_zzx/category_11198223.html?spm=1001.2014.3001.5482