zoukankan      html  css  js  c++  java
  • Balanced Ternary String CodeForces

    You are given a string ss consisting of exactly nn characters, and each character is either '0', '1' or '2'. Such strings are called ternary strings.

    Your task is to replace minimum number of characters in this string with other characters to obtain a balanced ternary string (balanced ternary string is a ternary string such that the number of characters '0' in this string is equal to the number of characters '1', and the number of characters '1' (and '0' obviously) is equal to the number of characters '2').

    Among all possible balanced ternary strings you have to obtain the lexicographically (alphabetically) smallest.

    Note that you can neither remove characters from the string nor add characters to the string. Also note that you can replace the given characters only with characters '0', '1' and '2'.

    It is guaranteed that the answer exists.

    Input

    The first line of the input contains one integer nn (3n31053≤n≤3⋅105, nn is divisible by 33) — the number of characters in ss.

    The second line contains the string ss consisting of exactly nn characters '0', '1' and '2'.

    Output

    Print one string — the lexicographically (alphabetically) smallest balanced ternary string which can be obtained from the given one with minimum number of replacements.

    Because nn is divisible by 33 it is obvious that the answer exists. And it is obvious that there is only one possible answer.

    Examples

    Input
    3
    121
    
    Output
    021
    
    Input
    6
    000000
    
    Output
    001122
    
    Input
    6
    211200
    
    Output
    211200
    
    Input
    6
    120110
    
    Outpu1201
    题目链接 :https://vjudge.net/problem/CodeForces-1102D
    题意:给你一个长度为N个字符串,N是3的倍数,字符串中只包括'0','1','2'这三个字符,
    题目让你修改最少数量的字符,使这个字符串的中的这三个字符的数量相等,
    即如果N=6,需要含有两个‘1’,两个‘2’,两个‘0’,并且希望你输出满足条件并且字典序最小的那一个。

    思路:
    贪心构造。
    先预处理一下每一个字符出现了多少次,
    然后遍历一下字符串,当0字符出现了大于n/3的时候,
    把'0'最后一个出现的位置尝试改成‘2’,如果‘2’的数量不小于n/3,那么就改成'1'。之所以这个顺序,就是因为要求字典序最小,这样构造出来的最小。
    ‘1’,’2’类推该怎么构造。
    既然我们每一次可能用到某一个字符第一次出现的位置或者最后一个出现的位置,我们就要开一个双端队列,然后预处理的时候把这个信息就加入到对应的双端中,
    注意:这里讲的最后一次出现的,是对于刚预处理完的,如果每一次把他的最后一个出现的给改成别的字符了,那么就要从双端中弹出,
    次后的继位。

    细节可以看代码:

    #include <iostream>
    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <cmath>
    #include <queue>
    #include <stack>
    #include <map>
    #include <set>
    #include <vector>
    #define rep(i,x,n) for(int i=x;i<n;i++)
    #define repd(i,x,n) for(int i=x;i<=n;i++)
    #define pii pair<int,int>
    #define pll pair<long long ,long long>
    #define gbtb ios::sync_with_stdio(false),cin.tie(0),cout.tie(0)
    #define MS0(X) memset((X), 0, sizeof((X)))
    #define MSC0(X) memset((X), '', sizeof((X)))
    #define pb push_back
    #define mp make_pair
    #define fi first
    #define se second
    #define gg(x) getInt(&x)
    using namespace std;
    typedef long long ll;
    inline void getInt(int* p);
    const int maxn=1000010;
    const int inf=0x3f3f3f3f;
    /*** TEMPLATE CODE * * STARTS HERE ***/
    int n;
    char s[maxn];
    char ans[maxn];
    int cnt[55];
    int num[11];
    deque<int> v[5];
    int main()
    {
        gbtb;
        cin>>n;
        cin>>s;
        strcpy(ans,s);
        repd(i,0,n-1)
        {
            if(s[i]=='0')
            {
                cnt[0]++;
                v[0].pb(i);
            }else if(s[i]=='1')
            {
                cnt[1]++;
                v[1].pb(i);
            }else
            {
                v[2].pb(i);
                cnt[2]++;
            }
        }
        int x=n/3;
    //    for(int i=n-1;i>=0;i--)
    //    {
    //        if(s[i]=='0')
    //        {
    //            if(cnt[0]>x)
    //            {
    //                if(cnt[2]<x)
    //                {
    //                    s[i]='2';
    //                    cnt[2]++;
    //
    //                }else
    //                {
    //                    s[i]='1';
    //                    cnt[1]++;
    //                }
    //                cnt[0]--;
    //            }
    //        }
    //    }
        repd(i,0,n-1)
        {
            if(s[i]=='0')
            {
                if(cnt[0]>x)
                {
                    int index=v[0].back();
                    v[0].pop_back();
    //                *(--v[0].end());
    //                v[0].erase(--v[0].end());
                    if(cnt[2]<x)
                    {
                        ans[index]='2';
                        cnt[2]++;
    
                    }else
                    {
                        ans[index]='1';
                        cnt[1]++;
                    }
                    cnt[0]--;
                }
            }
            else if(s[i]=='1')
            {
                if(cnt[1]>x)
                {
                    if(cnt[2]<x)
                    {
                        int index=v[1].back();
                            v[1].pop_back();
                        ans[index]='2';
                        cnt[2]++;
    
                    }else
                    {
                        int index=v[1].front();
                        v[1].pop_front();
                        ans[index]='0';
                        cnt[0]++;
                    }
                    cnt[1]--;
                }
            }else
            {
                if(cnt[2]>x)
                {
                    int index=v[2].front();
                        v[2].pop_front();
                    if(cnt[0]<x)
                    {
    
                        ans[index]='0';
                        cnt[0]++;
    
                    }else
                    {
                        ans[index]='1';
                        cnt[1]++;
                    }
                    cnt[2]--;
                }
            }
        }
        cout<<ans<<endl;
        return 0;
    }
    
    inline void getInt(int* p) {
        char ch;
        do {
            ch = getchar();
        } while (ch == ' ' || ch == '
    ');
        if (ch == '-') {
            *p = -(getchar() - '0');
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 - ch + '0';
            }
        }
        else {
            *p = ch - '0';
            while ((ch = getchar()) >= '0' && ch <= '9') {
                *p = *p * 10 + ch - '0';
            }
        }
    }
    
    
    


    本博客为本人原创,如需转载,请必须声明博客的源地址。 本人博客地址为:www.cnblogs.com/qieqiemin/ 希望所写的文章对您有帮助。
  • 相关阅读:
    【PL/SQL】学习笔记 (9)例外之 no_data_found
    【PL/SQL】学习笔记 (8)光标之带参数的光标
    【PL/SQL】学习笔记 (7)光标的属性,一个会话中打开光标数的限制
    【PL/SQL】学习笔记 (6)光标使用的具体示例--emp表涨工资
    Gps定位和wifi定位和基站定位的比较
    多态
    类加载,类初始化及对象实例化
    http和https工具类 (要注意httpclient版本号和log4j的版本号)
    js贪吃蛇
    局部变量,成员变量,静态变量
  • 原文地址:https://www.cnblogs.com/qieqiemin/p/10253246.html
Copyright © 2011-2022 走看看