2020牛客寒假算法基础集训营1 题目H:nozomi和字符串(尺取法)

题目描述:

nozomi看到eli在字符串的“花园”里迷路了,决定也去研究字符串问题。
她想到了这样一个问题:
对于一个 “01” 串而言,每次操作可以把 0 字符改为 1 字符,或者把 1 字符改为 0 字符。所谓 “01” 串,即只含字符 0和字符 1 的字符串。
nozomi有最多 K 次操作的机会。她想在操作之后找出一个尽可能长的连续子串,这个子串上的所有字符都相同。
nozomi想问问聪明的你,这个子串的长度最大值是多少?
注: K 次操作机会可以不全部用完。
如果想知道连续子串的说明,可以去问问eli,nozomi不想再讲一遍。

输入描述:

第一行输入两个正整数 nk
( 1 <= k <= n <= 200000)
输入仅有一行,为一个长度为 n 的、仅由字符 01 组成的字符串。

输出描述:

一个正整数,为满足条件的子串长度最大值。

分析:

此次使用尺取法解决,通过题目分析,可知存在两种情况,一、将字符 0 转换为字符 1,二、将字符1 转换为字符0,分两种情况讨论,取其中两种情况中最大值。在对每种情况讨论时,可以定义两个指针l 和r,分别指向区间的左端和右端,通过对指针的移动得到最长的连续字串

代码如下:
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
using namespace std;

const int MAXN = 200005;
string str;
int ans;
int n,k;

int Handle(char a,char b)   //Handle函数表示将 a字符 变为 b字符
{
	//l r 充当遍历字符串str的左右指针
	//change表示已经使用了多少次操作
	int res=1,l=0,r=0,change=0;
	for(int i=0;i<n;++i)
	{
		if(str[i] == a)
		{
			if(change < k)   //表示操作机会未用完
			{
				++r;
				++change;
			}
			else
			{
				//此操作保证l和r包围的区间内的a的总数保持不变 此区间中最多只包含k个字符a
				while(l <= r && str[l] != a) 
					l++;
				++l;
				++r;
			}
		}
		else
			++r;
		res = max(res,r-l);
	}
	return res;
}

int main()
{
	scanf("%d%d",&n,&k);
	cin >> str;
	ans = max(Handle('0','1'),Handle('1','0'));
	printf("%d\n",ans);
	return 0;
}
发布了33 篇原创文章 · 获赞 2 · 访问量 1712

猜你喜欢

转载自blog.csdn.net/weixin_42469716/article/details/104183319
今日推荐