程序设计思维 week5 作业C-平衡字符串

题目

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

Input

一行字符表示给定的字符串s。
1<=n<=10^5。
n是4的倍数。
字符串中仅包含字符 ‘Q’, ‘W’, ‘E’ 和 ‘R’。

Output

一个整数表示答案。

Sample Input

QQWE

Sample Output

1

思路

由于所求答案为一个连续区间且区间左右端点有明确移动方向,故可以采用尺取法。
当选中区间在范围内,即 R<n&&L<=R 时,循环。
假定已选中区间[L,R]:

  • 用 sum1, sum2, sum3, sum4 分别记录不包含区间 [L, R]这一段时,字符 ‘A’, ‘B’, ‘C’, ‘D’ 的个数;
  • MAX = max(sum1, sum2, sum3, sum4);
  • TOTAL=R–L+1;
  • FREE = TOTAL - [(MAX-sum1)+(MAX-sum2)+(MAX-sum3)+(MAX-sum4)]。

则FREE >=0且为4的倍数时,满足要求;否则不满足。
满足要求,则L++,同时比较此时所得区间长度与之前所得区间长度的最小值,更新ans=min(ans,R-L+1);否则R++

代码

#include <cstdio>
#include <algorithm>
#include <map>
using namespace std;
char c[100005];
map<char,int> sum;

int main() {
    int n=0;
    sum['Q']=0;sum['W']=0;sum['E']=0;sum['R']=0;
    while(scanf("%c",&c[n])!=EOF){
        sum[c[n]]++;
        n++;
    }
    if(sum['Q']==sum['W']&&sum['W']==sum['E']&&sum['E']==sum['R']){
        printf("0");
        return 0;
    }
    int l=0,r=0,ans=n;
    sum[c[0]]--;
    while(r<n&&l<=r){
        int Max=max(max(sum['Q'],sum['W']),max(sum['E'],sum['R']));
        int total=r-l+1;
        int free=total-(Max-sum['Q'])-(Max-sum['W'])-(Max-sum['E'])-(Max-sum['R']);
        if(free>=0&&free%4==0){//符合要求,左边界右移1
            ans=min(ans,total);
            sum[c[l]]++;
            l++;
        }
        else{//不符合要求,右边界右移1
            r++;
            if(r<n)
                sum[c[r]]--;
        }
    }
    printf("%d",ans);
    return 0;
}

总结

第一次用map,感觉十分快乐。
题目链接

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值