方法运用-小科的破键盘“尺取法”方法详解+代码——伟大的旭哥的博客

题目描述

小科是一名作家,他正在写一篇英文小说,可以将他的小说看成一个长长的字符串。然而不幸的是小科的键盘出了点问题,有部分按键无法使用了,确切地说只有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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值