• Codeforces Round #656 (Div. 3)D a-Good String(递归分治)


    地址:https://codeforces.com/contest/1385/problem/D

    题意:

    给定一个字符串s,长度为2的幂次
    规定一个字符串叫做c-good,如果它满足以下任意一个条件:

    1:字符串长度为1,左半边都是c,右半边是c+1--good

    2:字符串长度>1,左半边为c--good,右半边为c+1--good

    3:字符串长度>1,左半边为c+1--good,右半边为c--good

    求修改最少的字符使得s变成'a'-good

    解析:

    涉及到左,右半边,可以考虑用递归分治做。

    题目规定变成'a'--good,那么就从'a'入手,算出左半边全变成'a'用的次数和右半边用的次数,

    左半边变的话,递归进入右半边a+1

    右半边变的话,递归进入左半边a+1

    取个最小值即可

    #include<iostream>
    #include<cstring>
    #include<algorithm>
    #include<stack>
    #include<map>
    #include<map>
    using namespace std;
    typedef long long ll;
    const int mod=1e9+7;
    const int maxn=1e5+7;
    int l[maxn],r[maxn];
    int a[maxn];
    int b[8*maxn];
    int vis[maxn];
    ll c[maxn],d[maxn];
    int pos[maxn];
    const int maxn2=2e3+10;
    char mp[maxn2][maxn2];
    int dp[maxn2][maxn2];
    string s;
    int n;
    int len;
    int ac(int l,int r,char ch)
    {
        if(l==r)
            return s[l]!=ch;    //s[l]==ch,返回0,否则返回1,即修改
        int c1=0,c2=0;
        int md=(l+r)/2;
        for(int i=l;i<=md;i++)
            if(s[i]!=ch)
                c1++;
        for(int i=md+1;i<=r;i++)
            if(s[i]!=ch)
                c2++;
        c1+=ac(md+1,r,ch+1);
        c2+=ac(l,md,ch+1);
        return min(c1,c2);
    }
    int main()
    {
        int t;
        cin>>t;
        while(t--)
        {
            cin>>n;
            cin>>s;
            len=s.length();
            cout<<ac(0,len-1,'a')<<endl;
        }
    }
  • 相关阅读:
    创建Java项目报错处理
    samba服务器的安装及配置
    如何给Ubuntu 安装Vmware Tools
    Ubuntu切换至root用户
    网络打印机的配置
    tigervnc*
    163镜像地址
    浅谈数据库的完整性
    Android之获取本地图片并压缩方法
    网址收藏
  • 原文地址:https://www.cnblogs.com/liyexin/p/13471308.html
Copyright © 2020-2023  润新知