1. 程式人生 > >Balanced Ternary String CodeForces - 1102D (貪心+思維)

Balanced Ternary String CodeForces - 1102D (貪心+思維)

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 

s">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), '\0', 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 == '\n');
    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';
        }
    }
}