蓝桥杯 重复字符串

第十一届蓝桥杯

试题 F: 重复字符串

时间限制: 1.0s 内存限制: 256.0MB 本题总分:15 分
【问题描述】
如果一个字符串 S 恰好可以由某个字符串重复 K 次得到,我们就称 S 是
K 次重复字符串。例如 “abcabcabc” 可以看作是 “abc” 重复 3 次得到,所以
“abcabcabc” 是 3 次重复字符串。
同理 “aaaaaa” 既是 2 次重复字符串、又是 3 次重复字符串和 6 次重复字
符串。
现在给定一个字符串 S ,请你计算最少要修改其中几个字符,可以使 S 变
为一个 K 次字符串?
【输入格式】
输入第一行包含一个整数 K。
第二行包含一个只含小写字母的字符串 S 。
【输出格式】
输出一个整数代表答案。如果 S 无法修改成 K 次重复字符串,输出 − 1。
【样例输入】
2
aabbaa
【样例输出】
2
【评测用例规模与约定】
对于所有评测用例,1 ≤ K ≤ 100000, 1 ≤ | S | ≤ 100000。其中 | S | 表示 S 的
长度。

解析
以aabbac,k=3为例,即3个片段分别为aa bb ac,将这3个片段纵向排列比较:
在这里插入图片描述
在第一列的字母为aba,那么要让他们一样,只需要将b改为a即可,即aaa,由此可知,只需要找到这一列中哪个字母是最多的,那么剩下的字母都改为该字母是操作最少的。同理,第二列abc,由于a、b、c这三个字母在这一列中出现的次数是一样多的,那么这时就随便改,可以改为aaa或bbb或ccc均可。
上述可知,我们只需要统计每一列中出现次数最多的字母出现的次数即可,记为max,那么用一列的长度k减去max,即为该列需要更改的次数,第一列中的字母个数为3(即k值),a出现次数最多且出现了2次,故而在这一列中需要改变的次数为k-2=3-2=1,即该列需要改变1次。同理第二列为3-1=2,即该列需要改变2次。将这两列的次数相加1+2=3,故而需要改变至少3次。
也可以解释为如下:
在这里插入图片描述

程序如下:

#include <iostream>

using namespace std;

int main()
{
    int k = 0;
    string str;
    cin >> k;
    cin >> str;

    int size = str.size();
    if((size%k) != 0) {
        cout << -1;
        return 0;
    }

    int sum = 0;
    int alph[26];//记录该列中26个小写字母出现的次数
    int max = 0;//该列中出现的最大次数
    int temp = 0;
    for(int i=0; i<26; i++)
        alph[i] = 0;

    for(int i=0; i<size/k; i++){
        for(int j=i; j<size; j+=(size/k)){
            temp = (int)(str[j]-'a');
            alph[temp]++;
        }
        for(int m=0; m<26; m++)//找到该列中的最大值
            if(alph[m]>max) max = alph[m];

        sum += (k - max);//将所有列需要修改的次数全部加起来,k-max为需要修改的次数
        max = 0;//清零
        for(int n=0; n<26; n++)
            alph[n] = 0;//将数组清空
    }
    cout << sum << endl;
    return 0;
}
  • 15
    点赞
  • 28
    收藏
    觉得还不错? 一键收藏
  • 10
    评论
评论 10
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值