程序设计思维与实践 Week5 作业-C - 平衡字符串

题目

一个长度为 n 的字符串 s,其中仅包含 ‘Q’, ‘W’, ‘E’, ‘R’ 四种字符。
如果四种字符在字符串中出现次数均为 n/4,则其为一个平衡字符串。
现可以将 s 中连续的一段子串替换成相同长度的只包含那四个字符的任意字符串,使其变为一个平衡字符串,问替换子串的最小长度?
如果 s 已经平衡则输出0。
Input一行字符表示给定的字符串sOutput一个整数表示答案

Examples

Input

QWER

Output

0

Input

QQWE

Output

1

Input

QQQW

Output

2

Input

QQQQ

Output

3

Note

1<=n<=10^5
n是4的倍数
字符串中仅包含字符 ‘Q’, ‘W’, ‘E’ 和 ‘R’.

尺取法

在这里插入图片描述
在这里插入图片描述

什么情况下能使用尺取法?

在这里插入图片描述

思路

在这里插入图片描述
在这里插入图片描述

解法

step0 计算输入字符串中q w e r的个数分别保存在sumq sumw sume sumr中
step1 在sumq=sumw=sume=sumr时输出0,程序结束
step2 令r=-1,l=0,开始寻找能满足条件的最小区间,计算sumq\sumw\sume\sumr中的最大者,进而计算将四者补平所需要的空间数,计算r-l+1减去要补平的空间数剩余空间数是否正好为4的倍数,当满足时,转到step3,否则转到step4
step3 记录下与已记录的最小区间长度进行比较,当小于时更新最小区间长度。同时将l++,根据l~r中新减少的元素是什么对sumqwer进行更新,再判断新区间是否满足要求
step4 将r++,判断新加入l~r的元素是什么,更新sumqwer
step5 当r=n时结束更新,输出记录的最小区间即为所求

错误

1、字符串的定义和接收
形式1:

 string str;
 cin>>str;
 n=sizeof(str);

string用字节倍数的空间进行存储,不够的用空格补齐,sizeof()得到存储bit数,为8的倍数
还可写为str.size()
strlen()不可对string类型的变量使用
不可使用scanf("%s",str)录入
形式2:

 char str[10000]; 
 cin>>str;
  n=sizeof(str);

n为str数组的大小(10000)

n=strlen(str)

n为str中存储字符串的实际长度
其中cin>>str也可替换成scanf("%s",str);

积累

1、字符串的长度用sizeof()求
2、减少循环中if的判断次数,否则将会导致超时

代码

#include<iostream>
#include<math.h>
#include<string.h>
using namespace std;
int main()
{
	int n,sumq=0,sumw=0,sume=0,sumr=0;
//	char str[10000]; 
	string str;
	cin>>str;
//	scanf("%s",str);//错误形式
	 
	n=str.size();
//	cout<<n<<endl;
//	for(int i=0;i<n;i++)
//		cout<<str[i]<<'1';
	int ans=n+1;
	for(int i=0;i<n;i++)
	{
		if(str[i]=='Q')
			sumq++;
		else if(str[i]=='W')
			sumw++;
		else if(str[i]=='E')
			sume++;
		else if(str[i]=='R')
			sumr++;
	}
//	cout<<sumq<<' '<<sumw<<' '<<sume<<' '<<sumr<<endl;
	if(sumq==sumw&&sumw==sume&&sume==sumr)
		printf("0\n");
	else
	{
		int l=0,r=-1;
		while(r<n)
		{
			int maxx=max(max(sumq,sumw),max(sume,sumr));
			int total=r-l+1;
			total-=(maxx-sumq)+(maxx-sumw)+(maxx-sume)+(maxx-sumr);	
			if(l<=r&&total>=0&&total%4==0)
			{
				if(ans>(r-l+1))
					ans=r-l+1;
				if(str[l]=='Q')
					sumq++;
				else if(str[l]=='W')
					sumw++;
				else if(str[l]=='E')
					sume++;
				else if(str[l]=='R')
					sumr++;	
				l++;			
					}	
			else
			{
				r++;
				if(str[r]=='Q')
					sumq--;
				else if(str[r]=='W')
					sumw--;
				else if(str[r]=='E')
					sume--;
				else if(str[r]=='R')
					sumr--;		
				}	
		}
		printf("%d\n",ans);
	}
	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值